This question already has answers here:
How to calculate intersection of multiple arrays in JavaScript? And what does [equals: function] mean?
(18 answers)
Closed 1 year ago.
There is an array containing multiple sub-arrays, each with some elements.
For example:
const myArray = [[1,2,3],[2,3,4,5,6,7],[2,3,4],[2,3,6,11]];
in this case it should return [2,3] as these are the common elements in all sub-arrays.
Is there an efficient way to do that?
I wrote a function that does it for 2 sub-arrays, I don't think it's efficient to call it for every sub-array:
const filteredArray = array1.filter(value => array2.includes(value));
You could do like this:
const myArray = [[1, 2, 3], [2, 3, 4, 5, 6, 7], [2, 3, 4], [2, 3, 6, 11]];
const distinctValues = [...new Set(myArray.flat(1))];
const intersection = distinctValues.filter(x => myArray.every(y => y.includes(x)));
console.log(intersection);
You could reduce the array with filtering the nested arrays with a Set.
const
data = [[1, 2, 3], [2, 3, 4, 5, 6, 7], [2, 3, 4], [2, 3, 6, 11]],
common = data.reduce((a, b) => b.filter(Set.prototype.has, new Set(a)));
console.log(common);
Related
This question already has answers here:
Merge two arrays with alternating values
(14 answers)
Merge Two Arrays so that the Values Alternate
(6 answers)
interleave mutliple arrays in javascript
(2 answers)
Closed 1 year ago.
I have two arrays.
let a = [1, 3, 5, 7]
let b = [2, 4, 6, 8]
I want the result:
a = [1, 2, 3, 4, 5, 6, 7, 8]
How can I insert each of array B's elements every other element in array A?
I have tried using splice in a for loop, but the length of array A changes so I cannot get it to work.
You can create a new array, loop through a and push the current item and the item in b at the same index:
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8];
let res = []
a.forEach((e,i) => res.push(e, b[i]))
console.log(res)
Alternatively, you can use Array.map and Array.flat:
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8];
let res = a.map((e,i) => [e, b[i]]).flat()
console.log(res)
If the arrays have the same length, then you can use flat map to avoid mutating the original array.
const a = [1, 3, 5, 7];
const b = [2, 4, 6, 8];
const res = b.flatMap((elem, index) => [a[index], elem]);
console.log(res);
You can try:
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8]
let newArray = [...a, ...b]
console.log(newArray) // [1, 3, 5, 7, 2, 4, 6, 8]
If you want to sort just
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8]
let newArray = [...a, ...b].sort((a, b) => a - b)
console.log(newArray) // [1, 2, 3, 4, 5, 6, 7, 8]
Create a new array and flatten it by doing the below.
let a = [1, 3, 5, 7]
let b = [2, 4, 6, 8]
console.log(a.map((e, i)=> [e, b[i]]).flat());
You could transpose the data and get a flat array.
const
transpose = (a, b) => b.map((v, i) => [...(a[i] || []), v]),
a = [1, 3, 5, 7],
b = [2, 4, 6, 8],
result = [a, b]
.reduce(transpose, [])
.flat();
console.log(result);
Don't splice, just create a new array and push them in on every other index.
Do a for loop, and on each loop do
newArrary.push(a[i]);
newArrary.push(b[i]);
You can use reduce
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8];
let c = a.reduce((acc, x, i) => acc.concat([x, b[i]]), []);
console.log(c)
This works for arrays of any length, adapt the code based on the desired result for arrays that are not the same length.
Using forEach and pushing the current element and the relative element from the other array is an option
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8];
let c = [];
a.forEach((x, i) => {c.push(x, b[i])});
console.log(c);
More about forEach - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
If I have one array:
let x= [0,1,2,3,5]
And I have an array with several subarrays:
let winningIndices = [[0, 1, 2], [6, 7, 8], [0, 3, 6], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
How can I check if array x contains all of the elements of any one subarray.
In other words, how can I check if array x has combinations of either the numbers 0,1,2 or 6,7,8...
Thanks in advance
"How can I check if array x contains all of the elements of any one subarray."
Here's the most straightforward functional interpretation.
const won = winningIndices.some(indices=>
indices.every(
item=>x.includes(item)
)
)
This could be an option. If you'd like to remove xIncludesItem key from result, just map it again.
const winningIndices = [
[0, 1, 2],
[6, 7, 8],
[0, 3, 6],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
const x = [0, 1, 2, 3, 5];
const result = winningIndices
.map((item) => {
const xIncludesItem = item
.map((i) => x.includes(i))
.every(includes => includes);
return { item, xIncludesItem };
})
.filter(result => result.xIncludesItem);
console.log(result);
Array.includes is much slower than Set.has. A slightly more performant solution based on Ted Brownlow's solution would be:
const setX = new Set(x);
const won = winningIndices.some(indices=>
indices.every(
item=>setX.has(item)
)
)
Given multidimensional array (of any size and depth):
const multidimensionalArray = [1, [2, [3, [4, [5]]]], [6], [7, [8], [9]]];
I need to convert it into 2 dimensions array following example below (the idea is that each nested value should be converted into an array of all parents + this value).
Expected 2 dimensions array :
const twoDimensionsArray = [
[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4],
[1, 2, 3, 4, 5],
[1, 6],
[1, 7],
[1, 7, 8],
[1, 7, 9],
];
Could you please help me to solve the problem?
A recursive call for each nested array ought to do the trick.
NOTE: The following may not be complete for your use case - your data needs to be in a specific order for this to work - but I think this should be clean enough as an example:
const customFlatten = (arr, parents = [], output = []) => {
for (const item of arr) {
// If not an array...
if (!Array.isArray(item)) {
parents.push(item) // update parents for recursive calls
output.push(parents.slice(0)) // add entry to output (copy of _parents)
// If an array...
} else {
customFlatten(item, parents.slice(0), output) // recursive call
}
}
return output
}
console.log(customFlatten([1, [2, [3, [4, [5]]]], [6], [7, [8], [9]]]))
I'm trying to solve this problem. Essentially, I have a array of keys, and an array of values within objects, and I want those values to have keys.
Below is my best attempt so far - usually use python so this is a bit confusing for me.
var numbers = [3, 4, 5,6]
var selection = [[1, 2, 3, 4], [6, 5, 4, 3], [2, 9, 4]]
var result = [];
for (arr in selection) {
numbers.forEach(function (k, i) {
result[k] = arr[i]
})
};
console.log(result);
The output I'm looking for is like this,
results = [{3:1,4:2,5:3,6:4}, {..},..]
Love some pointers to getting the right output.
Note. This is for google appscript! So can't use certain javascript functions (MAP I think doesn't work, unsure of reduce).
Cheers!
Use map on selection and Object.assign
var numbers = [3, 4, 5, 6];
var selection = [
[1, 2, 3, 4],
[6, 5, 4, 3],
[2, 9, 4]
];
var result = selection.map(arr =>
Object.assign({}, ...arr.map((x, i) => ({ [numbers[i]]: x })))
);
console.log(result);
Create a separate function which take keys and values as arguments and convert it into object using reduce(). Then apply map() on selections and make an object for each subarray using that function
var numbers = [3, 4, 5,6]
var selection = [[1, 2, 3, 4], [6, 5, 4, 3], [2, 9, 4]]
function makeObject(keys, values){
return keys.reduce((obj, key, i) => ({...obj, [key]: values[i]}),{});
}
const res = selection.map(x => makeObject(numbers, x));
console.log(res)
Create a new object from scratch for each number array:
const selection = [
[1, 2, 3, 4],
[6, 5, 4, 3],
[2, 9, 4],
];
function objMaker(numarr) {
const numbers = [3, 4, 5, 6];
numarr.forEach((num, i) => (this[numbers[i]] = num));
}
console.info(selection.map(numarr => new objMaker(numarr)));
This question already has answers here:
Convert a 2D JavaScript array to a 1D array [duplicate]
(6 answers)
Closed 3 years ago.
I have this array
[[1,2,3][4,5,6][7,8,9]]
how to get from this such
[1,2,3,4,5,6,7,8,9]
without using Array.map
You can do:
const data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const result = data.reduce((a, c) => a.concat(c), []);
console.log(result);
You can use flat()
const arr = [[1,2,3],[4,5,6],[7,8,9]]
console.log(arr.flat())
If you don't want to use flat() then you can use push() and spread operator.
const arr = [[1,2,3],[4,5,6],[7,8,9]]
const res = [];
arr.forEach(x => res.push(...x))
console.log(res)
You can use array flat
let k = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
let m = k.flat();
console.log(m)
You can use Array.prototype.flat()
The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.
var arr = [[1,2,3],[4,5,6],[7,8,9]];
var res = arr.flat();
console.log(res);
use Array#flatMap method to flatten returned arrays.
let data = [
[1, 2, 3],[4, 5, 6],[7, 8, 9]
];
console.log(data.flatMap(a => a))
Or use Array#reduce method to iterate and reduce into a single array.
let data = [
[1, 2, 3],[4, 5, 6],[7, 8, 9]
];
console.log(data.reduce((arr, a) => [...arr, ...a]), [])
Or even you can use the built-in Array#flat method which is created for this purpose. If you want to fatten a nested array then specify the depth argument by default it would be 1.
let data = [
[1, 2, 3],[4, 5, 6],[7, 8, 9]
];
console.log(data.flat())