Flex 3 Actionscript Array Subtract function - arrays

Can anyone tell me how to compare two arrays and delete the common terms in ActionScript?
Eg:
Array1 = [2,4,6,8,10,12]
Array2 = [1,2,3,4,5,6,7,8,9,10,11]
Array1 - Array2 = [12]

If you use ActionLinq, it is very easy to do set mathematics like this:
var array1:Array = [2,4,6,8,10,12];
var array2:Array = [1,2,3,4,5,6,7,8,9,10,11];
var subtraction:Array = Enumerable.from(array1)
.except(Enumerable.from(array2))
.toArray();

You can filter using a custom function.
This is not an optimized way of filtering a difference of arrays, but it'll get the job done.
subtraction = Array1.filter(function(item:*, index:int, arr:Array){
var i:int;
var l:int;
l = Array2.length;
for ( i=0; i < l; i++ )
{
if ( Array2[i] == item )
{
return false;
}
}
return true;
});

If you wish to knock out all duplicates from an Array then I suggest that you use a Set to make the lookup speed as fast as possible:
const a : Array = [ 2, 3, 4 ];
const b : Array = [ 3, 4, 5 ];
// Create a Set for Array 'b' to provide a fast lookup table.
const setB : Object = {};
var prop : *;
for each (prop in b) {
setB[key] = true
};
// Find all values which only belong in Array 'a'.
const uniqueToA : Array = [];
for each (prop in a) {
if (setB[prop] === undefined) {
uniqueToA.push(prop);
}
}
If you find yourself doing a lot of work with collections then I would advise you invest in a Collections Framework such as AS3Commons Collections.

Related

loop to create array of arrays of same-length strings

I'm trying to create an array of arrays that are grouped according to their lengths (strings), such that the array below:
var testA = ["carts","carts","cars","cars","ca","ca", "ca","a","a","a","a"];
would become:
var sortedArrays = [["carts","carts"], ["cars","cars"],["ca","ca","ca"], ["a","a","a","a"]]
I am currently trying the loop below but simply cannot get this to work. I know it'll be something simple, but I've spent so long trying to complete this with no that it's proving incredibly frustrating.
var testA = ["carts","carts","cars","cars","ca","ca", "ca","a","a","a","a"];
var sortedArrays = [];
for(i=0; i < testA.length; i++){
longestWord = 0;
wordHolder = []
wordHolder.push(testA[i])
if (testA[i].length > longestWord){
longestWord = testA[i].length
wordHolder.push(testA[i])
}
sortedArrays.push(wordHolder)
}
Any help will be greatly appreciated
What about the following code (Swift, but it should be easy to reformulate it in other languages):
let testA = ["carts","carts","cars","cars","ca","ca", "ca","a","a","a","a"]
var maxLength = 0
for string in testA {
if string.count > maxLength { maxLength = string.count }
}
var sortedArrays: [[String]] = []
for nextLength in 0 ... maxLength {
let invertedLength = maxLength - nextLength
let nextArray = testA.filter { $0.count == invertedLength }
sortedArrays.append(nextArray)
}
This code creates also empty arrays, which can of course easily be skipped.
The question, of course, is what your requirements are. The code above is compact, but it is not fast for large arrays...
For large arrays, it would be better, first to sort testA, and then to extract the elements.
Sticking with java script, I was able to do the following. My assumption is the words are already sorted descending by length and that there is only one word of each length. That's based on what you were doing. I think what was going on is that too much was getting initialized or reset each time through the loop.
var testA = ["carts", "carts", "cars", "cars", "ca", "ca", "ca", "a", "a", "a", "a"];
var sortedArrays = [];
var wordHolder = []; // took outside loop to ensure initialized
var curLength = testA[0].length;// assuming here that testA not empty
for (var i = 0; i < testA.length; i++) {
if (testA[i].length === curLength) { // more of the same
wordHolder.push(testA[i]);
} else { // new block starts
curLength = testA[i].length;
sortedArrays.push(wordHolder);
// alert (wordHolder)
// alert (sortedArrays)
wordHolder = [];
wordHolder.push(testA[i]);
}
}
sortedArrays.push(wordHolder);// add the last one

How to search a subarray of numbers inside an array of numbers

my issue is this in TypeScript (now latest is v3.1)
I have a array of numbers
let mainArray : Array<number> = [1,2,3,4];
I have to find subarray of [2,3], how can i do?
My actual workaround is converting both arrays in string (toString()) and using .includes (ES6) function, and it works but i think is not the best solution.
Thank you!
You can use filter for this
let mainArray : Array<number> = [1,2,3,4];
var findArry = [2, 3];
var subArray = mainArray.filter(function(val) {
return findArry.indexOf(val) != -1 ? true : false;
});
console.log(subArray);
Well its more algorithm problem then typescript problem. But this solution should work for checking if there is subarray which matched with searched array:
const toTuples = (n) => (item, index, originalArr) => {
const arr = [];
for(let i = 0; i < n; i++) {
arr.push(originalArr[index + i]);
}
return arr;
}
const arr = [1,2,3,4,2,3];
const search = [2, 3];
const mapped = arr.map(toTuples(search.length));
console.log(mapped.some((currArray) => currArray.every((item) => search.includes(item))));

How to apply search filter on 2 different arrays in Ionic 2?

I have applied search filter on a array using this code in my listproduct.ts
if (val && val.trim() != '') {
this.names = this.names.filter((names) => {
return (names.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
Note that this filter is applied on names array. I wish this filter should also work on catg and pservice named arrays too.
How can I achieve filter result on multiple arrays?
You can create another bigArray which is the concatenation of your three arrays using js concat function :
var bigArray = this.names.concat(this.catg, this.pservice);
and call your filter on that bigArray.
var val = "test";
this.names = ["abc", "test123", "test"];
this.catg = ["qsd", "azetest"];
this.pservice = ["another test !", "tss"];
this.bigArray = this.names.concat(this.catg, this.pservice);
// here, bigArray contains all values of the three arrays (abc,test123,test,qsd,azetest,another test !,tss)
if (val && val.trim() != '') {
this.bigArray = this.bigArray.filter((names) => {
return (names.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
// here, bigArray contains only filtered values of the three arrays (test123,test,azetest,another test !)
Here is a working Plunker
If you need to keep them as separate arrays, and cannot concat them, you could do something like this:
let names = ["Andy", "Alex", "Corbyn", "Eric" ];
let catg = ["Adventure", "Action", "Comedy", "SciFi"];
let pservice = ["Example", "Service", "Allo"]
let val = "a";
[names, catg, pservice] = [names, catg, pservice].map(array => {
return array.filter((item) => {
return (item.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
});
console.log(names);
console.log(catg);
console.log(pservice);

JS - filter array of objects by array of property values and return array of filtered objects

I am trying (in js or jquery) to filter array of objects and return array of objects that have particular property name.
I tried filter and find functions like this:
var objs = [{ a:1, }, {a:2}, {a:3}, {a:4}]
var vals = [1, 2]
function callback(obj) {
var arr = arr || []
console.log(arr)
$.each(vals, function(key, val) {
if ( val == obj.a ) {
arr.push(obj)
}
})
}
var result = objs.find(callback);
console.log(">>>", result)
Expected result is:
result = [{a:1}, {a:2}]
However it doesnt work because each iteration of find starts over and defines arr all over again.
I could ofcourse make is with two nested $.each() - one to iterate through array of objects and second to iterate through array of property values but i consider is as last option - looking for something more elegant, shorter. Do you guys have any ideas?
You could do it with a filter and indexOf.
var objs = [{ a:1, }, {a:2}, {a:3}, {a:4}]
var vals = [1, 2]
function filterByValue(source, allowedValues) {
// Return the result of the filter.
return source.filter(item => {
// Returns true when `a` is present in vals (index > -1); otherwise it returns false.
return allowedValues.indexOf(item.a) > -1;
});
}
const
filteredArray = filterByValue(objs, vals);
console.log(filteredArray)
Thijs's answer works, but will get unperformant as the vals array gets large. To get O(n) complexity, you could build a set out of the allowedValues array:
var objs = [{ a:1, }, {a:2}, {a:3}, {a:4}]
var vals = [1, 2]
function filterByValue(source, allowedValues) {
allowedValues = new Set(allowedValues)
// Return the result of the filter.
return source.filter(item => {
// Returns true when `a` is present in vals, otherwise it returns false.
return allowedValues.has(item.a);
});
}
const filteredArray = filterByValue(objs, vals);
console.log(filteredArray)

AS3 Finding common values in Arrays

I'm struggling with something that shouldn't be too difficult but I can't figure it out I have a number of Arrays with different values and I want to find the common values all of the Arrays have, see example below:
var arrayOne:Array = ["1","2","3"];
var arrayTwo:Array = ["1","2","7"];
var arrayThree:Array = ["1","2","9","12"];
_resultArray = ["1","2"];
Any help is appreciated.
You can do something like:
///Returns common values between to arrays
function getCommonValues(array1:Array, array2:Array):Array
{
var len1:int = array1.length;
var len2:int = array2.length;
var toReturn:Array = new Array();
for(var i:int = 0; i < len1; i++){
for(var n:int = 0; n < len2; n++){
if(array1[i] == array2[n]){
toReturn.push(array1[i]);
}
}
}
return toReturn;
}
Then do something like:
var arrayOneAndTwo:Array = getCommonValues(arrayOne,arrayTwo);
var _resultArray:Array = getCommonValues(arrayOneAndTwo,arrayThree);
Optionally you can modify the function to include all three arrays in the comparison, which would be more efficient.
Edit
If you want to process an unknown amount of arrays you can add:
///Returns common values between X number of sub arrays
function getCommonValuesFromSubArrays(papaArray:Array):Array
{
if(papaArray.length < 2){ return papaArray; }
var toReturn:Array = papaArray[0];
for(var a:int = 1; a < papaArray.length; a++){
toReturn = getCommonValues(toReturn, papaArray[a]);
}
return toReturn;
}
Then something like:
var arr1:Array = ["one","two","three","four","five"];
var arr2:Array = ["one","two","five","six"];
var arr3:Array = ["one","two","three","four","five"];
var arr4:Array = ["one","two","three","four","five"];
var bigOlArray:Array = [arr1,arr2,arr3,arr4];
var _results:Array = getCommonValuesFromSubArrays(bigOlArray);
I would use a function to concatenate all arrays, sort by numerical value, and collect all items that are available exactly as many times as the number of arrays that were passed in as parameters:
var arrayOne : Array = [ "1", "2", "3" ];
var arrayTwo : Array = [ "1", "2", "7" ];
var arrayThree : Array = [ "1", "2", "9", "12" ];
// you can pass in any number of Arrays
trace ( searchArraysForCommonItems ( arrayOne, arrayTwo, arrayThree ) ); // returns ["1", "2"]
function searchArraysForCommonItems ( ...args : * ) : Array
{
var searchArray : Array = [];
for each ( var arr:Array in args)
searchArray = searchArray.concat ( arr );
var resultArray : Array = [];
var last : String;
var times : int = 0;
for each ( var str : String in searchArray.sort ( Array.NUMERIC ))
if (last == str) times++;
else
{
if (times == args.length) resultArray.push ( last );
last = str;
times = 1;
}
return resultArray;
}
Of course, you can (and should) use Vector.<String> instead of Array wherever possible to improve performance, but always remember that Array.sort() is a native function and very fast...
I would use the Array.filter() Function to achieve this:
var _resultArray:Array = arrayOne.filter(
function(item:String, index:int, arr:Array):Boolean
{
return (arrayTwo.indexOf(item) != -1 && arrayThree.indexOf(item));
}
);
This will loop over arrayOne and return an array with the values that both appear also in arrayTwo and arrayThree.
Edit: And here is a function that will take any number of arrays and return the common values:
function getCommonValues(arrayOne:Array, ... arrays:Array):Array
{
var _resultArray:Array = arrayOne.filter(
function(item:String, index:int, arr:Array):Boolean
{
return arrays.every(
function (a:Array, index2:int, arr2:Array):Boolean
{
return a.indexOf(item) != -1;
}
);
}
);
return _resultArray;
}
Usage:
resultArray = getCommonValues(arrayOne, arrayTwo, arrayThree, arrayFour);
The function has another nested closure inside the first one, so might be a bit hard to understand, but I tested it, it works.

Resources