Merging array of arrays - javascript

The problem, I'm trying to solve is as followed
we do have an array
const array = [[1, 2, 3], ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"],["+", "-", "*", "/", "?"]];
we want to have an output like this:
const output = [[1,"A","+"],[1,"A","-"],[1,"A","*"],[1,"A","/"],[1,"A","?"],[1,"B","+"],[1,"B","-"],[1,"B","*"],[1,"B","/"],[1,"B","?"],[1,"C","+"],[1,"C","-"],[1,"C","*"],[1,"C","/"],[1,"C","?"],[1,"D","+"],[1,"D","-"],[1,"D","*"],[1,"D","/"],[1,"D","?"],[1,"E","+"],[1,"E","-"],[1,"E","*"],[1,"E","/"],[1,"E","?"],[1,"F","+"],[1,"F","-"],[1,"F","*"],[1,"F","/"],[1,"F","?"],[1,"G","+"],[1,"G","-"],[1,"G","*"],[1,"G","/"],[1,"G","?"],[1,"H","+"],[1,"H","-"],[1,"H","*"],[1,"H","/"],[1,"H","?"],[1,"I","+"],[1,"I","-"],[1,"I","*"],[1,"I","/"],[1,"I","?"],[1,"J","+"],[1,"J","-"],[1,"J","*"],[1,"J","/"],[1,"J","?"],[2,"A","+"],[2,"A","-"],[2,"A","*"],[2,"A","/"],[2,"A","?"],[2,"B","+"],[2,"B","-"],[2,"B","*"],[2,"B","/"],[2,"B","?"],[2,"C","+"],[2,"C","-"],[2,"C","*"],[2,"C","/"],[2,"C","?"],[2,"D","+"],[2,"D","-"],[2,"D","*"],[2,"D","/"],[2,"D","?"],[2,"E","+"],[2,"E","-"],[2,"E","*"],[2,"E","/"],[2,"E","?"],[2,"F","+"],[2,"F","-"],[2,"F","*"],[2,"F","/"],[2,"F","?"],[2,"G","+"],[2,"G","-"],[2,"G","*"],[2,"G","/"],[2,"G","?"],[2,"H","+"],[2,"H","-"],[2,"H","*"],[2,"H","/"],[2,"H","?"],[2,"I","+"],[2,"I","-"],[2,"I","*"],[2,"I","/"],[2,"I","?"],[2,"J","+"],[2,"J","-"],[2,"J","*"],[2,"J","/"],[2,"J","?"],[3,"A","+"],[3,"A","-"],[3,"A","*"],[3,"A","/"],[3,"A","?"],[3,"B","+"],[3,"B","-"],[3,"B","*"],[3,"B","/"],[3,"B","?"],[3,"C","+"],[3,"C","-"],[3,"C","*"],[3,"C","/"],[3,"C","?"],[3,"D","+"],[3,"D","-"],[3,"D","*"],[3,"D","/"],[3,"D","?"],[3,"E","+"],[3,"E","-"],[3,"E","*"],[3,"E","/"],[3,"E","?"],[3,"F","+"],[3,"F","-"],[3,"F","*"],[3,"F","/"],[3,"F","?"],[3,"G","+"],[3,"G","-"],[3,"G","*"],[3,"G","/"],[3,"G","?"],[3,"H","+"],[3,"H","-"],[3,"H","*"],[3,"H","/"],[3,"H","?"],[3,"I","+"],[3,"I","-"],[3,"I","*"],[3,"I","/"],[3,"I","?"],[3,"J","+"],[3,"J","-"],[3,"J","*"],[3,"J","/"],[3,"J","?"]]
We dont't know the size of the parent Array and children can have various sizes and types

#pilchard has point out this solution: All possible combinations of a 2d array in Javascript
function combos(list, n = 0, result = [], current = []){
if (n === list.length) result.push(current)
else list[n].forEach(item => combos(list, n+1, result, [...current, item]))
return result
}
I can confirm that it works

#Andrew
I tried this approach let me know if it will work.
const array = [
[1, 2, 3],
["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"],
["+", "-", "*", "/", "?"]
];
let result;
let innerArray;
innerArray = array[0].map(a1 =>
array[1].map(a2 =>
array[2].map(a3 => [a1, a2, a3])
)
)
result = innerArray.flat(2)
console.log("Result", result)

You can use an inner map:
const array = [
[1, 2, 3],
['A', 'B', 'C'],
['+', '-', '*']
];
const res = array.map((e, i) => array.map(f => f[i]))
console.log(res)

Related

How to remove duplicates array in multidimensional array where the key positions might not same in JavaScript?

let originalArray = [
["A", "B", "C"],
["B", "A", "C"],
["D", "E", "F"]
];
let uniqueArray = originalArray.filter((item, index, self) => {
return index === self.findIndex((t) => JSON.stringify(t) === JSON.stringify(item));
});
console.log(uniqueArray);
I want this result:
[
["A", "B", "C"],
["D", "E", "F"]
];
To remove duplicates from a multidimensional array in JavaScript, where the key positions might not be the same, you can use a combination of Array.prototype.map(), Array.prototype.filter(), and Array.prototype.includes() to create a new array with only unique elements.
You can use an object with Array.prototype.reduce, storing a stringified version of the sorted values as the cache.
let originalArray = [
["A", "B", "C"],
["B", "A", "C"],
["D", "E", "F"]
];
let uniqueArray = Object.values(originalArray.reduce((acc, cur) => {
const data = [...cur].sort();
const key = JSON.stringify(data);
acc[key] = acc[key] ?? cur;
return acc;
}, {}));
console.log(uniqueArray);
You can sort the inner arrays before inserting them into a Set for filtering.
let originalArray = [
["A", "B", "C"],
["B", "A", "C"],
["D", "E", "F"]
];
let vis = new Set;
let res = originalArray.filter(x => {
const str = JSON.stringify([...x].sort());
return !vis.has(str) && vis.add(str);
});
console.log(res);

How to change places in an Array?

There's a list of 5 elements. Per default, the list (array) should show ["A", "B", "C", "D", "E"]. Every second the elements should rotate by one position:
List after 1 second: ["B", "C", "D", "E", "A"];
After 2 seconds: ["C", "D", "E", "A", "B"];
After 3 seconds: ["D", "E", "A", "B", "C"];
I'm learning and I need help. How would you solve this problem? This is my incorrect solution:
const testArray = ["A", "B", "C", "D", "E"];
const swap = function(theArray, indexA, indexB) {
let temp = theArray[indexA];
theArray[indexA] = theArray[indexB];
theArray[indexB] = temp;
};
swap(testArray, 0, 1);
console.log(testArray);
For no reason other than it's stupidly short.
let r = ['A','B','C','D','E'];
setInterval(_ => {r.push(r.shift());console.log(r)},1000)
You can try array.shift method:
const arr = [1, 2, 3, 4, 5];
setInterval(() => {
const firstElement = arr.shift();
arr.push(firstElement);
console.log(arr);
}, 1000);
this is a shorter version of the swap
const testArray = ["A", "B", "C", "D", "E"];
const swap = function(theArray) {
theArray.push(theArray.shift())
};
swap(testArray);
console.log(testArray);
You can shift the first element off the array, and then push it to the end of the array.
const arr = ['A', 'B', 'C', 'D', 'E'];
function swap(arr) {
// Log the joined array
console.log(arr.join(''));
// `shift` the first element off the array
// and `push` it back on
arr.push(arr.shift());
// Repeat by calling `swap` again after
// one second, passing in the updated array
setTimeout(swap, 1000, arr);
}
swap(arr);
Addition documentation
setTimeout

Sum string arrays and subarrays in javascript without concatenating them

I am trying to "sum" the items from one array to another, preserving their children (subarrays):
array1 = [ array2 = [ array3 = [
[ [ [
"A", "1", "A",
"B", "2", "B",
[ [ "1",
"C" + "3" = "2",
] ] [
], ], "C",
"D" "4" "3"
] ] ]
],
"D",
"4"
]
Edit: Ideally the longest array would be treated as the "main" array (its values ​​would come before the shortest array).
If the arrays have the same number of elements, the first array is the main.
["a", ["b", "c"], "d"]
+
["x", ["v", "w"], "y"]
=
["a" "x", ["b", "c", "v", "w"], "d", "y"]
["a", "b", ["c", "d", ["e", "f"]]]
+
[["1", ["2"]]]
=
["a", "b", ["c", "d", "1", ["e", "f", "2"]]]
Would it be possible? so far the only suggestions I've found are related to the use of .concat(), however it concatenates one array at the end of the other, and does not merge both:
var array1 = [["A", "B", ["C"]], "D"];
var array2 = [["1", "2", ["3"]], "4"];
console.log(array1.concat(array2)) // returns [["A", "B", ["C"]], "D", ["1", "2", ["3"]], "4"]
Edit 2:
I've been thinking about the problem in a different way now, and realized that an easy way to visualize it is like this:
target = [
"A",
"B",
[
"C",
"D",
[
"E"
],
"J"
]
]
I want to add the following element after "E":
newelement = [
[
[
"F",
[
"G",
"H",
"I"
]
]
]
]
the result would be:
result = [
"A",
"B",
[
"C",
"D",
[
"E",
"F",
[
"G",
"H",
"I"
]
],
"J"
]
]
so that's basically it, merging one array with another.
If I understand correctly you want to concat subsections of both arrays that consist only of non-arrays (the number of elements may differ), then merge the next arrays of both recursively, and then apply again the first logic to the next subsections having no arrays... etc.
Here is that idea implemented:
function deepConcat(a, b) {
if (a.length < b.length) return deepConcat(b, a);
let i = 0, j = 0, result = [];
while (true) {
while (i < a.length && !Array.isArray(a[i])) result.push(a[i++])
while (j < b.length && !Array.isArray(b[j])) result.push(b[j++])
if (i >= a.length || j >= b.length) break;
result.push(deepConcat(a[i++], b[j++]));
}
return [...result, ...a.slice(i), ...b.slice(j)];
}
const test = (a, b) => console.log(JSON.stringify(deepConcat(a, b)));
test([["A", "B", ["C"]], "D"], [["1", "2", ["3"]], "4"]);
test(["a", ["b", "c"], "d"], ["x", ["v", "w"], "y"]);
test(["a", "b", ["c", "d", ["e", "f"]]], [["1", ["2"]]]);
test(["A","B",["C","D",["E"],"J"]], [[["F",["G","H","I"]]]]);
Something like this?
array1 = [
["A", "B", ["C"]], "D"
]
array2 = [
["1", "2", ["3"]], "4"
]
array3 = [
["A", "B", "1", "2", ["C", "3"]], "D", "4"
]
const findFirstNonPrimitiveIndex = arr => arr.findIndex(x => !isPrimitive(x))
const takePrimitives = (arr, pos = 0) => arr.slice(0, findFirstNonPrimitiveIndex(arr))
const isPrimitive = x => typeof x !== "object"
const merge = (arr1, arr2) => {
const [head1, ...rest1] = arr1
const [head2, ...rest2] = arr2
// base case
if (rest1.length === 0)
if (isPrimitive(head1)) return [head1, head2];
else return [merge(head1, head2)]
// inductive step
if (isPrimitive(head1)) {
const cutPoint = findFirstNonPrimitiveIndex(rest1);
return [
...takePrimitives(arr1),
...takePrimitives(arr2),
...merge(rest1.slice(cutPoint), rest2.slice(cutPoint))
]
} else {
return [merge(head1, head2), ...merge(rest1, rest2)];
}
}
const result = merge(array1, array2);
console.log(result)
.as-console-wrapper {
top: 0;
max-height: 100% !important;
}

how to get the x values from the sorted 'y' array [duplicate]

I have 2 arrays:
[2, 4, -2, 4, 1, 3]
["a", "b", "c", "d", "e", "f"]
and I want them to be sorted by the numerical array:
// output
[-2, 1, 2, 3, 4, 4] // <-sorted by numerical order
["c", "e", "a", "f", "b", "d"] // sorted exactly the same order as the first array
while its actually not important if "b" or "d" comes first (they both have 4 in this example)
I found many questions about this online but none of them worked for me can anyone help me with that?
You could sort the keys of the first array based on their value. This will return an array with indices of the array sorted based on the value of numbers array. Then use map to get the sorted values based on the indices
const numbers = [2, 4, -2, 4, 1, 3],
alphabets = ["a", "b", "c", "d", "e", "f"]
const keys = Array.from(numbers.keys()).sort((a, b) => numbers[a] - numbers[b])
const sortedNumbers = keys.map(i => numbers[i]),
sortedAlphabets = keys.map(i => alphabets[i])
console.log(
sortedNumbers,
sortedAlphabets
)
A standard method is to take the indices of the key array for sorting and sort the indices as pattern for all other arrays by taking the index and the value from the key array.
At the end map the sorted arrays.
var array1 = [2, 4, -2, 4, 1, 3],
array2 = ["a", "b", "c", "d", "e", "f"],
indices = [...array1.keys()].sort((a, b) => array1[a] - array1[b]);
[array1, array2] = [array1, array2].map(a => indices.map(i => a[i]));
console.log(...array1);
console.log(...array2);
I would recommend storing the entire thing in a Map. That way, you can independently sort the first array however you want and then use those values as keys to call respective value of second array.
You can do this in a single line by associating your two arrays and then ordering the items:
const x = ["a", "b", "c", "d", "e", "f"]
const y = [2, 4, -2, 4, 1, 3]
const result = y.map((val, index)=>({x:x[index], y:val})).sort((a,b)=>a.y-b.y).map(v=>v.x)
// -> ["c", "e", "a", "f", "b", "d"]

Use index of array to find the corresponding index in a filtered version of that array

Given the following array:
const arr = ["a", "c", "b", "c", "b"]
And given an index of 4, how can we return the index of the corresponding element in ["b", "b"]? In this example, the answer is 1.
More generally, how can we use the index of arr to find the corresponding index of b in arr2 where const arr2 = arr.filter(item => item === "b")?
Examples:
["a", "c", "b", "c", "b"][4] corresponds to ["b", "b"][1]
["a", "c", "b", "c", "b", "b"][4] corresponds to ["b", "b", "b"][1]
Inputs and expected outputs
function getCorrespondingIndexInFilteredArray(array, index, filterValue) {...}
getCorrespondingIndexInFilteredArray(["a", "c", "b", "c", "b"], 4, "b") // 1
getCorrespondingIndexInFilteredArray(["a", "c", "b", "c", "b", "b"], 4, "b") // 1
getCorrespondingIndexInFilteredArray(["b", "b"], 0, "b") // 0
getCorrespondingIndexInFilteredArray(["b", "b"], 1, "b") // 1
getCorrespondingIndexInFilteredArray(["a", "a"], 0, "b") // either 0 or -1 is alright here
You can use slice() upto the given index and then get the count of elements which are equal to element at given index.
const arr = ["a", "b", "c", "b"]
const other = (arr, ind) => {
return arr.slice(0,ind).reduce((ac, a) => a === arr[ind] ? ac + 1: ac, 0);
}
console.log(other(arr,3))
console.log(other(arr,1))
You could use a counter object and a for loop
function customIndex(arr, index) {
const counter = {};
for (let i = 0; i < arr.length; i++) {
counter[arr[i]] = counter[arr[i]] + 1 || 0;
if (index === i)
return counter[arr[i]]
}
return 'index out of bound'
}
console.log(customIndex(["a", "b", "c", "b"], 3))
console.log(customIndex(["a", "a", "b", "a"], 3))
console.log(customIndex(["a", "a", "b", "a"], 1))
You could filter the array to get the items which match arr[index] but only until index. (This will not short circuit like this first snippet)
const customIndex = (arr, index) =>
arr.filter((n, i) => n === arr[index] && i <= index).length - 1
console.log(customIndex(["a", "b", "c", "b"], 3))
console.log(customIndex(["a", "a", "b", "a"], 3))
console.log(customIndex(["a", "a", "b", "a"], 1))

Categories

Resources