Concat Arrays with For Loop - arrays

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());

Related

How to remove empty arrays from an array of 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);

Iterate through Swift array and change values

I need to change values of a Swift array.
My first try was to just iterate through but this does not work as I only get a copy of each element and the changes do not affect the origin array.
Goal is to have a unique "index" in each array element.
myArray = [["index": 0], ["index":0], ["index":0], ["index":0]]
counter = 0
for item in myArray {
item["index"] = counter
counter += 1
}
My next attempt was using map but I don't know how to set an increasing value. I could set the $0["index"] = 1 but I need an increasing value.
In which way would this be possible using map?
myArray.map( { $0["index"] = ...? } )
Thanks for any help!
The counter in a for loop is a constant. To make it mutable, you could use :
for var item in myArray { ... }
But that won't be helpful here since we'd be mutating item and not the elements in myArray.
You could mutate the elements in myArray this way :
var myArray = [["index": 0], ["index":0], ["index":0], ["index":0]]
var counter = 0
for i in myArray.indices {
myArray[i]["index"] = counter
counter += 1
}
print(myArray) //[["index": 0], ["index": 1], ["index": 2], ["index": 3]]
The counter variable is not needed here :
for i in myArray.indices {
myArray[i]["index"] = i
}
A functional way of writing the above would be :
myArray.indices.forEach { myArray[$0]["index"] = $0 }
I found a simple way and would like to share it.
The key is the definition of myArray. It would success if it's in this way:
let myArray : [NSMutableDictionary] = [["firstDict":1, "otherKey":1], ["secondDict":2, "otherKey":1], ["lastDict":2, "otherKey":1]]
myArray.enumerated().forEach{$0.element["index"] = $0.offset}
print(myArray)
[{
firstDict = 1;
index = 0;
otherKey = 1;
}, {
index = 1;
otherKey = 1;
secondDict = 2;
}, {
index = 2;
lastDict = 2;
otherKey = 1;
}]
How about a more functional approach by creating a brand new array to store the modified dictionaries:
let myArray = [["index": 0], ["index":0], ["index":0], ["index":0]]
let myNewArray = myArray.enumerated().map { index, _ in ["index": index] }

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))));

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)

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