Reputation: 15367
I have a 2 Dimensional array consisting of values, for example:
const arr = [ [ 1, 2, 3, 4, 5, 6 ],
[ 7, 8, 9, 0, 1, 2 ],
[ 3, 4, 5, 6, 7, 8 ],
[ 9, 0, 1, 2, 3, 4 ] ];
The number of rows can vary, though will always be a multiple of two.
How can I extract columns out of this array using .map()
so that I can get sub-arrays each containing two columns?
Example:
// columns 1 and 2:
ext1 = [ [ 1, 2 ],
[ 7, 8 ],
[ 3, 4 ],
[ 9, 0 ] ];
// columns 3 and 4:
ext2 = [ [ 3, 4 ],
[ 9, 0 ],
[ 5, 6 ],
[ 1, 2 ] ];
// columns 5 and 6:
ext3 = [ [ 5, 6 ],
[ 1, 2 ],
[ 7, 8 ],
[ 3, 4 ] ];
Upvotes: 4
Views: 3760
Reputation: 9858
You can make a function like this that selects columns based on an array of indices:
const getColumns = (arr, indices) => arr.map(row => indices.map(i => row[i]));
getColumns(arr, [0, 1]); // returns the first two columns
If the ultimate aim is to split the array into equal size chunks you could do it like this:
const splitIntoColumnGroups = (arr, width) =>
[...Array(Math.ceil(arr[0].length/width)).keys()].map(i =>
arr.map(row =>
row.slice(i * width, (i + 1) * width)));
Upvotes: 7
Reputation: 4217
const arr=[[1,2,3,4,5,6],[7,8,9,0,1,2],[3,4,5,6,7,8],[9,0,1,2,3,4]];
const columns = (arr,cols) => arr.map(e => e.slice(...cols))
console.log(columns(arr,[0,2]))
console.log(columns(arr,[1,4]))
Upvotes: 2
Reputation: 5054
If you really want to use map you can do this,
const arr = [ [ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 0, 1, 2],
[ 3, 4, 5, 6, 7, 8],
[ 9, 0, 1, 2, 3, 4] ];
const prev = {};
arr.map((curr) => {
let counter = 1;
while(curr.length > 0) {
let splittedArr = curr.splice(0, 2);
if(prev[`ext${counter}`]) {
prev[`ext${counter}`] = [...prev[`ext${counter}`], splittedArr]
} else {
prev[`ext${counter}`] = [splittedArr]
}
counter++;
}
});
console.log(prev);
But you can do the following using reduce,
const arr = [ [ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 0, 1, 2],
[ 3, 4, 5, 6, 7, 8],
[ 9, 0, 1, 2, 3, 4] ];
const res = arr.reduce((prev, curr) => {
let counter = 1;
while(curr.length > 0) {
let splittedArr = curr.splice(0, 2);
if(prev[`ext${counter}`]) {
prev[`ext${counter}`] = [...prev[`ext${counter}`], splittedArr]
} else {
prev[`ext${counter}`] = [splittedArr]
}
counter++;
}
return prev;
}, {});
console.log(res);
Upvotes: 0
Reputation: 122047
You could do this with reduce
and forEach
method and inside you can check if the remainder is 0 and then add current and next element to the current column.
const arr = [ [ 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 0, 1, 2], [ 3, 4, 5, 6, 7, 8], [ 9, 0, 1, 2, 3, 4] ];
const columns = arr.reduce((r, a, i) => {
let col = 0;
a.forEach((e, j) => {
if (!r[col] && a[j + 1]) r[col] = []
if (j % 2 == 0) {
r[col].push([e, a[i + 1]])
col++
}
})
return r;
}, [])
console.log(columns)
Upvotes: 1
Reputation: 4371
You can do it with using map
and filter
as:
const arr = [ [ 1, 2, 3, 4, 5, 6 ],
[ 7, 8, 9, 0, 1, 2 ],
[ 3, 4, 5, 6, 7, 8 ],
[ 9, 0, 1, 2, 3, 4 ] ];
function fn(array, firstIndex, secondIndex) {
return array.map(a => a.filter((b,i) => i == firstIndex || i == secondIndex));
}
var result = fn(arr, 2, 3);
console.log(result);
Upvotes: 3