How to remove empty arrays from an array of arrays? - arrays

I have an array of arrays which includes some empty arrays.
Exp. [ [Name1],[Name2],[Name3],[],[] ]
I tried using shift and splice (example code given)
function RemoveEmptyArrays(){
var NameArray = [[Name1],[Name2],[Name3],[],[]];
for (i = 0; i < NameArray.length; i++) {
if ( NameArray[i][0] === undefined ) {
NameArray.splice( i, 1 );
}
}
Logger.log(arrayvals);
}
Desired Output:
[ [Name1],[Name2],[Name3] ]

You want to retrieve from [[Name1],[Name2],[Name3],[],[]] to [ [Name1],[Name2],[Name3] ].
If my understanding is correct, how about this sample script?
Sample script:
var NameArray = [["Name1"],["Name2"],["Name3"],[],[]];
var res = NameArray.filter(function(e) {return e.length})
console.log(res)
Modified script:
If your script is modified, how about this modification?
var NameArray = [["Name1"],["Name2"],["Name3"],[],[]];
for (i = NameArray.length - 1; i >= 0; i--) { // Modified
if ( NameArray[i][0] === undefined ) {
NameArray.splice(i, 1);
}
}
console.log(NameArray);
Reference:
filter()

A very simple way to do this is using the spread operator from ES6 and then concat.
'concat' concatenates arrays to another array, and the spread operator takes an array and passes it to a function as if they were parameters (among other things).
Here's a working fiddle
const arr = [['a', 'b', 'c'], ['d', 'e', 'f'], [] ,[]] ;
const result = [].concat(...arr)
console.warn(result);

Related

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)

Concat Arrays with For Loop

After experimenting with the reduce method to flatten an array, I tried using a similar approach with a for-loop.
Can anyone explain why the for-loop doesn't flatten the array using concat?
P.S. I know that I can use a nested for-loop with Array.isArray to flatten as well. Just expected concat to work in a for-loop after seeing how reduce flattened the array.
var arrays = [
[1, 2, 3],
[4, 5],
[6]
];
console.log(arrays.reduce(function(arr, elem) {
return arr.concat(elem);
}, []));
function flatten(arr) {
var flat = [];
for (var i = 0; i < arr.length; i++) {
flat.concat(arr[i]);
}
return flat;
}
console.log(flatten(arrays));
concat doesn't modify the array. To make your code work, you'd have to assign the value to it, then it'll do the same
var arrays = [[1,2,3], [4,5], [6]];
function flatten(arr) {
var flat = [];
for (var i = 0; i < arr.length; i++) {
flat = flat.concat(arr[i]);
}
return flat;
}
console.log(flatten(arrays));
Just a sidenote - with ES6, you can flatten an array even easier using the spread operator [].concat(...arr);
var arrays = [[1,2,3], [4,5], [6]];
function flatten(arr) {
return [].concat(...arr);
}
console.log(flatten(arrays));
And nowadays even easier, using flat()
const arrays = [[1,2,3], [4,5], [6]];
console.log(arrays.flat());

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.

Flex 3 Actionscript Array Subtract function

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.

Resources