I have multidimensional array with strings:
const arr = [['a', 'b'], ['c', 'd'], ['d', 'a']]
How can i log to console all values that occur in all nested arrays more than 1 time? (For this example function should console.log 'a' and 'd').
Thanks for the help
You first flat the arr.Then remove duplicates from it using Set. And loop through it then compare lastIndexOf and indexOf
const arr = [['a', 'b'], ['c', 'd'], ['d', 'a']]
let flat = arr.toString().split(',');
[... new Set(flat)].forEach(a => {
if(flat.indexOf(a) !== flat.lastIndexOf(a)) console.log(a)
})
let findDupesInMDArray = (arr) => {
// flatten the array
const flat = arr.flat();
// filter for dupes
return flat.filter((item, index) => flat.indexOf(item) != index)
}
let array = [['a', 'b'], ['c', 'd'], ['d', 'a']]
const dupes = findDupesInMDArray(array)
console.log(dupes)
Using spread syntax, Array#flat, Array#reduce, Array#filter and Array#map.
const arr = [['a', 'b'], ['c', 'd'], ['d', 'a']]
const res = Array.from(arr.flat().reduce((a,c)=>{
return a.set(c, (a.get(c)||0) + 1);
}, new Map()))
.filter(([,c])=> c > 1)
.map(([k])=>k);
console.log(res);
You could count the items by using a Map and get only the items with a count greater than one.
const
count = (m, a) => Array.isArray(a) ? a.reduce(count, m) : m.set(a, (m.get(a) || 0) + 1);
var array = [['a', 'b'], ['c', 'd'], ['d', 'a']],
result = Array
.from(array.reduce(count, new Map), ([k, v]) => v > 1 && k)
.filter(Boolean)
console.log(result);
Here's a more basic approach:
var array = [['a', 'b'], ['c', 'd'], ['d', 'a']]
var result = [];
for (var i in array){
for (var l in array[i]){
if(array[i][l]==='a'||array[i][l]==='d')
result.push(array[i][l])
}}
var unique = new Set(result) //creates a set with unique values
console.log(unique) //should log the set {'a','d'}
What we're doing here is
looping through the nested arrays twice
pushing the elements (if the element === 'a' or element ==='d') into a new array called result.
creating a new set with the unique values only
Related
Given an array of arrays, how do I convert this to a JavaScript object with the condition that the first element of each array of the internal arrays will be a key of a new JavaScript object, the subsequent element would be the value?
And if there is more than one occurrence of the element in the first position of the internal arrays only create a single key corresponding to this element.
For example:
var arr = [['a', 'b'], ['c', 'd'], ['a', 'e']]
should return:
var obj = {a: ["b", "e"], c: ["d"]}
Here there are 2 occurrences of a within arr therefore only a single key a was created in obj along with c
Using Array.prototype.reduce function, you can accomplish this as follows.
var arr = [['a', 'b'], ['c', 'd'], ['a', 'e']];
const output = arr.reduce((acc, cur) => {
acc[cur[0]] ? acc[cur[0]].push(cur[1]) : acc[cur[0]] = [ cur[1] ];
return acc;
}, {});
console.log(output);
This is an alternative:
var arr = [['a', 'b'], ['c', 'd'], ['a', 'e']]
const obj = {}
arr.forEach(([k, v]) => obj[k] = [...obj[k] ?? [], v])
I am trying to loop through nested arrays and reorder them into new nested arrays. For example, take [[a,b,c,d], [e,f,g,h], [i,j,k,l]] and change it into [[a,e,i], [b,f,j], [c,g,k], [d,h,l]]
let rowArr = [[a,b,c,d], [e,f,g,h], [i,j,k,l]];
let newRowArr = [];
let length = rowArr.length;
for(let i = 0; i<length; i++){
for(let j = 0; j<rowArr.length; j++){
newRowArr.push(rowArr[i][j]);
j+=rowArr.length;
}
console.log(newRowArr) //I get only [a,e,i]
I am missing something obvious but why won't it loop the additional times to push the other letters into the array?
You could just use the nested loop where i and j are names for outer in inner index names and then use them to add to new array as result[j][i] = current inner loop value
let arr = [
['a', 'b', 'c', 'd'],
['e', 'f', 'g', 'h'],
['i', 'j', 'k', 'l']
];
const result = []
arr.forEach((a, i) => {
a.forEach((e, j) => {
if (!result[j]) result[j] = []
result[j][i] = e
})
})
console.log(result)
You can use Array.prototype.map:
let rowArr = [['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']];
let newRowArr = [];
let arraySize = 4;
const arrayColumn = (arr, n) => arr.map(x => x[n]);
for (let i = 0; i < arraySize; i++) {
newRowArr.push(arrayColumn(rowArr, i));
}
console.log(newRowArr);
I have this multidimensional array:
points= [['1','2','3'], ['4','5','6'] ]
and i have this array of points needed for a check in the above array;
new_points = [ 'a','b', 'c', 'd', 'e', 'f']
So a goes to 1 (0,0) , b to 2 (0,1) etc so points becomes;
points= [['a','b','c'], ['d','e','f'] ]
the multi-dimension array will always be 3 by 3, 4 by 4 etc.
Use two .map() and in nested function get index of relevant item of new_points based on map index.
var points= [['1','2','3'], ['4','5','6']];
var new_points = [ 'a','b', 'c', 'd', 'e', 'f'];
var newArr = points.map(function(item, i){
return item.map(function(val, j){
return new_points[(item.length*i)+j];
});
});
console.log(newArr);
If points is 2 dimensional but the nested array can be of variable length then you can reduce points using a counter to help get the item from new_points:
const points = [[1], [2, 3]];
const new_points = ['a', 'b', 'c'];
const createNewPoints = (points, new_points) =>
points.reduce(
([result, counter], items) => [
result.concat([
items.map((_, i) => new_points[i + counter]),
]),
counter + items.length,
],
[[], 0],
)[0];
console.log(createNewPoints(points, new_points));
You could shift each element of new_points by mapping the original array structure.
var points = [['1', '2', '3'], ['4', '5', '6']],
new_points = ['a', 'b', 'c', 'd', 'e', 'f'];
points = points.map(a => a.map(Array.prototype.shift, new_points));
console.log(points);
How to concat all this array into a single array:
[Array(10), Array(10), Array(10), Array(10), Array(10), Array(10), Array(10), Array(2)]
You can use ES6's spread:
var arrays = [[1, 2], [3, 4], [5, 6]];
var res = [].concat(...arrays);
console.log(res);
Use reduce and concat
var output = arr.reduce( (a, c) => a.concat(c), []); //assuming arr is the input array
Edit
As #TJ mentioned in his comment, that above solution will create some intermediate arrays along the way, you can try (concat without spread)
var output = [].concat.apply([], arr);
or
var output = Array.prototype.concat.apply([], arr); //avoiding usage of another unnecessary array `[]`
var array1 = ['a', 'b', 'c'];
var array2 = ['d', 'e', 'f'];
console.log(array1.concat(array2));
// expected output: Array ["a", "b", "c", "d", "e", "f"]
If you have an array of array you can do like so :
let bigArray = new Array();
arrayOfArray.forEach((arr) => {
bigArray.concat(arr);
});
I have two arrays:
a = [
[a, b],
[c, d],
[e, f],
[g, h]
]
b = [
[a, 4],
[1, 2],
[e, 3]
]
when a[i][0], matches b[i][0], I need to add a value to the current index of a. For this example, when a[0][1] matches b[0][1], a[0][1] should look like [a,b,new_value].
If this means creating a new array with all of the values of a, that is fine, but the original values and order of a cannot change.
I have tried numerous variations of for loops and reverse for loops. I am at a loss.
Thanks in advance.
Not too bad with a map + find. For each item of the a array, see if there is a matching element in the b array, and if so, add your new value:
const a = [
["a","b"],
["c","d"],
["e","f"],
["g","h"],
];
const b = [
["a",4],
[1,2],
["e",3],
];
const mapped = a.map(x => {
const match = b.find(y => y[0] === x[0]);
if (match) return [...x, "new value"] // Replace "new value" with whatever you want to add...
return x;
});
console.log(mapped)
Iterate the 1st array with Array#map. Compare each sub array's 1st item to a sub array in the 2nd array at the same index. If they match, concat a value to the sub array from the 1st array, and return it. If not, return the sub array.
Note: concat and map create new arrays, and don't change the original.
var a = [["a","b"],["c","d"],["e","f"],["g","h"]];
var b = [["a",4],[1,2],["e",3]];
var result = a.map(function(item, i) {
return b[i] && item[0] === b[i][0] ? item.concat(b[i][1]) : item; // replace b[i][1] with whatever value you want to add
});
console.log(result);
You could map the result of the check by using a default value, if the length of the given arrays are different.
var array1 = [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g', 'h']],
array2 = [['a', 4], [1, 2], ['e', 3]],
result = array1.map((a, i) => a.concat(a[0] === (array2[i] || [])[0] ? array2[i][1] : []));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }