Reputation: 25
I got this matrix that, depending on the results I receive from the server, the width can change. Basically, it can be something like
[undefined, undefined]
[1, 2, 3, 4]
[1, 2]
[undefined, undefined, undefined]
[1, 2, 3, 4, 5, 6]
and I want it to be like this
[undefined, 1, 1, undefined, 1]
[undefined, 2, 2, undefined, 2]
[undefined, 3,undefined, undefined, 3]
[undefined, 4, undefined, undefined, 4]
[undefined, undefined, undefined, undefined, 5]
[undefined, undefined, undefined, undefined, 6]
Notice that the height changed to the maximum width of the first example. I googled it and the best solution I got was this
array.map((row, i) => array.map(col => col[i]))
but this solution wont change my matrix height. I tried 2 for cycles but I think I didn't code it right as I was not getting the expected result. If someone could give me a little help, that would be awesome
Upvotes: 0
Views: 897
Reputation: 3118
The more efficient solution:
const maxLength2d = (matrix) => {
let result = 0
for (const { length } of matrix) result = Math.max(result, length)
return result
}
const transpose2d = (matrix, placeholder = undefined) => {
const result = []
const maxlen = maxLength2d(matrix)
let y = 0
for (const { length } = matrix; y < length; y++) {
const inner = matrix[y]
let x = 0
for (const { length } = inner; x < length; x++) {
result[x] ||= []
result[x].push(inner[x])
}
for (; x < maxlen; x++) {
result[x] ||= []
result[x].push(placeholder)
}
}
return result
}
const transposed = transpose2d(
[
[1, 2],
['a', 'b', 'c', 'd'],
]
)
console.log('transposed', transposed)
console.log('transposed back', transpose2d(transposed))
Upvotes: 0
Reputation: 24181
There are a few steps involved here.
Find the max length.
Normalise
And then rotate
I've placed comments in code to show each part.
const input = [
[undefined, undefined],
[1, 2, 3, 4],
[1, 2],
[undefined, undefined, undefined],
[1, 2, 3, 4, 5, 6]
];
//first find max length
const maxw = Math.max(...input.map(m => m.length));
//now normalize
const norm_inputs = input.map(m =>
(new Array(maxw)).concat(m).slice(-maxw)
);
//now rotate..
const output = (new Array(maxw).fill(0)).map(
(row, i) => norm_inputs.map(col => col[i]))
Upvotes: 0
Reputation: 548
Assuming your matrix is stored in matrix
,
const transformed = [];
const maxWidth = matrix.reduce((max, current) => {
return (current.length > max) ? current.length : max;
}, 0);
// Loop over each column
for (let i = 0; i < maxWidth; i++) {
const tRow = [];
// Loop over each row of the current column
for (const row of matrix) {
tRow.push(row[i]);
}
transformed.push(tRow);
}
Upvotes: 0
Reputation: 106017
There are a lot of ways to solve this (as other answers demonstrate). Here's how I'd do it, as it minimizes the number of times we iterate over the data.
const data = [
[undefined, undefined],
[1, 2, 3, 4],
[1, 2],
[undefined, undefined, undefined],
[1, 2, 3, 4, 5, 6],
];
// get the length of the longest array
const maxLen = data.reduce((max, {length}) => Math.max(max, length), 0);
// make a new set of arrays
const result = Array.from({ length: maxLen }, (_, i) => data.map(col => col[i]));
console.log(result);
Upvotes: 4