I have below array format and i want to make union of it using lodash or normal js.
var testArray = [[1,2,3,4,5,6,7,8],[1,2,3,4,5,10,7,8],[1,2,3,6,7,8],[9],[3,4,5]]
I want to make union of all these into one and output should be below array.
testArray = [1,2,3,4,5,6,7,8,9,10]
You could combine flattenDeep with _.union. If needed apply sorting
var testArray = [[1,2,3,4,5,6,7,8],[1,2,3,4,5,10,7,8],[1,2,3,6,7,8],[9],[3,4,5]],
result = _.chain(testArray)
.flattenDeep()
.union();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Apply _.union() to the parent array:
var testArray = [[1,2,3,4,5,6,7,8],[1,2,3,4,5,10,7,8],[1,2,3,6,7,8],[9],[3,4,5]];
var result = _.union.apply(_, testArray);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
Or use array spread if ES6 is supported:
const testArray = [[1,2,3,4,5,6,7,8],[1,2,3,4,5,10,7,8],[1,2,3,6,7,8],[9],[3,4,5]];
const result = _.union(...testArray);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
With ES6 you can do this using spread syntax ... and Set
var testArray = [[1,2,3,4,5,6,7,8],[1,2,3,4,5,10,7,8],[1,2,3,6,7,8],[9],[3,4,5]]
var result = [...new Set([].concat(...testArray))];
console.log(result)
You can just call _.union.apply(null, arrays). It is documented here:
https://lodash.com/docs/#union
> var testArray = [[1,2,3,4,5,6,7,8],[1,2,3,4,5,10,7,8],[1,2,3,6,7,8],[9],[3,4,5]]
> lodash.union.apply(null, testArray)
[ 1, 2, 3, 4, 5, 6, 7, 8, 10, 9 ]
The apply trick is to transform your array of array in to function call arguments. If you need it sorted as well, you can just tuck .sort() at the end of it.
In just ES5 if you need that:
var flattened = Object.keys(testArray.reduce(function(acc, cur) {
cur.forEach(function(v) {acc[v] = true;});
return acc;
}, {})).sort(function(a, b) {return a - b;});
Related
Is there a shorter way of doing this:
let arrSlicePush = arr.slice();
arrSlicePush.push(num);
let x = func(arrSlicePush);
Thanks in advance.
Simply do:
func([...arr, num]);
Worth noting that Array.push returns the length of the array anyway, so the first example is irrelevant.
You would call Array.prototype.concat instead of Array.prototype.push.
Also, since concat already merges two arrays and returns a new one, you so not even need to slice the original array.
const arr = [ 0, 1, 2, 3, 4 ];
const num = 5;
const func = (arr) => arr.map(e => String.fromCharCode(e + 65));
const x = func(arr.concat(num));
console.log(x);
Notes
[ ...arr, val ] is syntactic sugar for arr.concat(val)
This works:
func(animals.slice().concat(num));
The following code
function steamrollArray(arr) {
// I'm a steamroller, baby
return arr.flat();
}
steamrollArray([1, [2], [3, [[4]]]]);
returns
arr.flat is not a function
I tried it in Firefox and Chrome v67 and the same result has happened.
What's wrong?
The flat method is not yet implemented in common browsers (only Chrome v69, Firefox Nightly and Opera 56). It’s an experimental feature. Therefore you cannot use it yet.
You may want to have your own flat function instead:
Object.defineProperty(Array.prototype, 'flat', {
value: function(depth = 1) {
return this.reduce(function (flat, toFlatten) {
return flat.concat((Array.isArray(toFlatten) && (depth>1)) ? toFlatten.flat(depth-1) : toFlatten);
}, []);
}
});
console.log(
[1, [2], [3, [[4]]]].flat(2)
);
The code was taken from here by Noah Freitas originally implemented to flatten the array with no depth specified.
This can also work.
let arr = [ [1,2,3], [2,3,4] ];
console.log([].concat(...arr))
Or for older browsers,
[].concat.apply([], arr);
Array.flat is not supported by your browser. Below are two ways to implement it.
As a function, the depth variable specifies how deep the input array structure should be flattened (defaults to 1; use Infinity to go as deep as it gets) while the stack is the flattened array, passed by reference on recursive calls and eventually returned.
function flat(input, depth = 1, stack = [])
{
for (let item of input)
{
if (item instanceof Array && depth > 0)
{
flat(item, depth - 1, stack);
}
else {
stack.push(item);
}
}
return stack;
}
As a Polyfill, extending Array.prototype if you prefer the arr.flat() syntax:
if (!Array.prototype.flat)
{
Object.defineProperty(Array.prototype, 'flat',
{
value: function(depth = 1, stack = [])
{
for (let item of this)
{
if (item instanceof Array && depth > 0)
{
item.flat(depth - 1, stack);
}
else {
stack.push(item);
}
}
return stack;
}
});
}
Similar issue, solved by using ES6 .reduce() method:
const flatArr = result.reduce((acc, curr) => acc.concat(curr),[]);
use _.flatten from lodash package ;)
var arr=[[1,2],[3,4],[5,6]];
var result=[].concat(...arr);
console.log(result); //output: [ 1, 2, 3, 4, 5, 6 ]
Another simple solution is _.flattenDeep() on lodash
https://lodash.com/docs/4.17.15#flattenDepth
const flatArrays = _.flattenDeep([1, [2], [3, [[4]]]]);
console.log(flatArrays);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
const array = [
[
[6, 6],
[3, 3],
],
[[7, 7, [9]]],
]
function simplifyArray(array) {
const result = []
function recursivePushElem(arr) {
arr.forEach(i => {
if (Array.isArray(i)) recursivePushElem(i)
else result.push(i)
})
}
recursivePushElem(array)
console.log(result)
return result
}
simplifyArray(array)
you could simply use this [].concat(...objArrs) that would work the same as the flat() method and allow more compatibility in browsers
You can set your full array to a string then split it. .toString().split(',')
Updated due to community bot.
So basically if you want to flatten out an array that does contain any objects but strictly strings or numbers, by using .toString() it converts each element of the array to a string (if it isn't already), and then joins all of the elements together using a comma as a separator.
Once we have our string all separated by a comma we can use .split() to create an array.
NOTE*** The reason this wont work with objects is that .toString() will return [object object] as it is the default string representation of an object in JavaScript.
If your array consists solely of numbers than you would need to map through your array and convert each string number value to a number.
const array1 = [
['one', 'oneTwo'],
'two',
'three',
'four',
]
console.log('a1', array1.toString().split(','))
const numberArray = [1, 2, [3, 4, [5, 6]], [[7, [8,9]]], 10];
console.log(numberArray.toString().split(',').map(num => Number(num)));
Not sure if it is a valid answer however in my attemp to flat an array I employed the destructuring_assignment introduced in ES6.
// typeScriptArray:Array<Object> = new Array<Object>();
let concatArray = [];
let firstArray = [1,2,3];
let secondArray = [2,3,4];
concatArray.push(...firstArray);
concatArray.push(...secondArray);
console.log(concatArray);
It works like a charm even though I'm not sure if any broswer compatibily issues may arise.
Say you have an array-like Javascript ES6 Iterable that you know in advance will be finite in length, what's the best way to convert that to a Javascript Array?
The reason for doing so is that many js libraries such as underscore and lodash only support Arrays, so if you wish to use any of their functions on an Iterable, it must first be converted to an Array.
In python you can just use the list() function. Is there an equivalent in ES6?
You can use Array.from or spread syntax (...).
Example:
const x = new Set([ 1, 2, 3, 4 ]);
const y = Array.from(x);
console.log(y); // = [ 1, 2, 3, 4 ]
const z = [ ...x ];
console.log(z); // = [ 1, 2, 3, 4 ]
Summary:
Array.from() function, it takes an iterable as in input and returns an array of the iterable.
Spread syntax: ... in combination with an array literal.
const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);
const newArr1 = [ ...map ]; // create an Array literal and use the spread syntax on it
const newArr2 = Array.from( map ); //
console.log(newArr1, newArr2);
Caveat when copying arrays:
Be cognizant of the fact that via these methods above only a shallow copy is created when we want to copy an array. An example will clarify the potential issue:
let arr = [1, 2, ['a', 'b']];
let newArr = [ ...arr ];
console.log(newArr);
arr[2][0] = 'change';
console.log(newArr);
Here because of the nested array the reference is copied and no new array is created. Therefore if we mutate the inner array of the old array, this change will be reflected in the new array (because they refer to the same array, the reference was copied).
Solution for caveat:
We can resolve the issue of having shallow copies by creating a deep clone of the array using JSON.parse(JSON.stringify(array)). For example:
let arr = [1, 2, ['a', 'b']]
let newArr = Array.from(arr);
let deepCloneArr = JSON.parse(JSON.stringify(arr));
arr[2][0] = 'change';
console.log(newArr, deepCloneArr)
You can use the Array.from method, which is being added in ES6, but only supports arrays and iterable objects like Maps and Sets (also coming in ES6). For regular objects, you can use Underscore's toArray method or lodash's toArray method, since both libraries actually have great support for objects, not just arrays. If you are already using underscore or lodash, then luckily they can handle the problem for you, alongside adding various functional concepts like map and reduce for your objects.
The following approach is tested for Maps:
const MyMap = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
const MyArray = [...MyMap].map(item => {
return {[item[0]]: item[1]}
});
console.info( MyArray ); //[{"a", 1}, {"b", 2}, {"c": 3}]
<Your_Array> = [].concat.apply([], Array.from( <Your_IterableIterator> ));
You could also do the following, but both approaches are certainly not recommendable (merely a proof-of-concept for completeness):
let arr = [];
for (let elem of gen(...)){
arr.push(elem);
}
Or "the hard way" using ES5 + generator function (Fiddle works in current Firefox):
var squares = function* (n) {
for (var i = 0; i < n; i++) {
yield i * i;
}
};
var arr = [];
var gen = squares(10);
var g;
while (true) {
g = gen.next();
if (g.done) {
break;
}
arr.push(g.value);
}
I have an array and I want to put it in another array using indexes.
For example:
arry[1].push(sub_array_1)
array[2].push (sub_array_2)
But I get an error if I write:
var sub_array_1 = [1, 2, 2, 2, 2];
arry[1].push(sub_array_1)
Using spread operator
var subArray = [1, 4, 6, 7];
var mainArray = [6, 7, 8];
var index = 1;
mainArray = [...mainArray.slice(0, index), subArray, ...mainArray.slice(index)];
Assuming:
var arry = [9,8,7];
var sub_array_1 = [1,2,2,2,2];
If you are trying to insert sub_array_1 into arry, as a single element, just use splice directly:
arry.splice(1, 0, sub_array_1);
The result will be:
[9,[1,2,2,2,2],8,7]
On the other hand, if you are trying to insert the contents of sub_array_1 before the second element of arry, you can do something like this:
Array.prototype.splice.apply(arry, [1, 0].concat(sub_array_1));
The result will be:
[9,1,2,2,2,2,8,7]
Here is a more general function:
function insert(arrayDest, index, arraySrc) {
Array.prototype.splice.apply(arrayDest, [index, 0].concat(arraySrc));
}
[EDITED]
Starting with ES6, you can simplify the above code using the spread operator (...). For example:
function insert(arrayDest, index, arraySrc) {
arrayDest.splice(index, 0, ...arraySrc);
}
You're using wrong syntax! Follow the either below mentioned approach.
var sub_array_1 = [1,2,2,2,2];
arry[1] = sub_array_1;
// OR
var sub_array_1 = [1,2,2,2,2];
arry.push(sub_array_1);
.push(ele) will add an item to an array, thereby incrementing the length of array by 1. Remember array index starts at 0.
If you need to add an item(array/object/other) to a particular index, use [index]. Eg: arry[0] = [1,23]; arry[1] = [4,5,6,7];
obj.arrayOne.push(arrayLetters);
or
obj['arrayOne'].push(arrayLetters);
let array = []
array.push({"index": 0, "value":100})
console.log(array)
maybe it helping for you
I have a JSON response like this:
{"result":[["abc","de"],["fgh"],["ij","kl"]]}
I want the response to be in the form:
{"result":["abc","de","fgh","ij","kl"]}
How can I achieve this?
From the mozilla docs
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
// flattened is [0, 1, 2, 3, 4, 5]
var test={"result":[["abc","de"],["fgh"],["ij","kl"]]};
var tmp=[];
for(var i in test.result){
for(var j in test.result[i]){
tmp.push(test.result[i][j]);
}
}
test.result=tmp;
alert(JSON.stringify(test));
jsfiddle link http://jsfiddle.net/fu26849m/
jsFiddle
var arrayToFlatten = [[0, 1], [2, 3], [4, 5]];
Native (from Merge/flatten an array of arrays in JavaScript?):
var flattenedNative = arrayToFlatten.reduce(function(a, b) {
return a.concat(b);
});
alert(flattenedNative); // 0,1,2,3,4,5
jQuery (from How to flatten array in jQuery?):
var flattenedJQuery = $.map(arrayToFlatten, function(n) {
return n;
});
alert(flattenedJQuery); // 0,1,2,3,4,5
Native alternative (from Merge/flatten an array of arrays in JavaScript?):
var flattenedNativeAlt = [].concat.apply([], arrayToFlatten);
alert(flattenedNativeAlt); // 0,1,2,3,4,5
My first suggestion for this is you should create json directly as you want to use.
Do not modify it after you get.
You can also use this , this will give you value as you want.:
var mainText= JSON.parse('{"result":[["abc","de"],["fgh"],["ij","kl"]]}');
var arr = [];
for(var val1 in mainText.result)
{
arr = arr.concat(mainText.result[val1]);
}
mainText.result = arr;
console.log(JSON.stringify(mainText));
The reduce() and concat() functions can be combined to flatten an array:
var json = {"result":[["abc","de"],["fgh"],["ij","kl"]]};
function concatArrays(a, b) { return a.concat(b); }
json.result = json.result.reduce(concatArrays);
console.log(json); //{"result":["abc","de","fgh","ij","kl"]}
See it in action:
http://jsfiddle.net/cazomufn/
I like lodash' flatten (if you can live with another dependency.)
json.result = _.flatten(json.result);
// { result:['abc','de','fgh','ij','kl'] }
For example reduce isn't supported before IE9 but lodash would still work (compatibility build).