having 2d number array like;
const arr = [
[1, 5, 9],
[2, 7, 8],
[3, 0, 6],
];
what is the simplest way to get sorted array of array indexes where sort critera is values of original 2d array?
result should be:
`[2,1]`, // (value=0)
`[0,0]`, // (value=1)
`[2,0]`, // (value=2)
`[0,1]`, // (value=3)
...
btw, actual values are floats not that it matters.
but complexity does matter as loop runs on each frame.
You could get the indices first and sort them by the value of the matrix.
const
array = [[1, 5, 9], [2, 7, 8], [3, 0, 6]],
result = array
.flatMap((a, i) => a.map((_, j) => [i, j]))
.sort((a, b) => array[a[0]][a[1]] - array[b[0]][b[1]]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Something like this?
const arr = [
[1, 5, 9],
[2, 7, 8],
[3, 0, 6],
];
const map = []
arr.forEach((row, rowIndex) => row.forEach((col, colIndex) => {
map.push({ c: colIndex, r: rowIndex, value: col });
}))
console.log(map)
const sorted = map.sort((a, b) => {
if(a.value === b.value) return 0;
return a.value > b.value ? 1 : -1;
})
console.log(sorted)
console.log(sorted.map(v => [v.r, v.c]))
it's working version, not optimalized
EDIT: little optimalization with execution time measure:
const arr = [
[1, 5, 9],
[2, 7, 8],
[3, 0, 6],
];
const sortFn = (a, b) => a.value === b.value ? 0 : a.value > b.value ? 1 : -1;
let count = 3;
function process(arr) {
const map = []
arr.forEach((row, rowIndex) => row.forEach((col, colIndex) => {
map.push({ row: rowIndex, col: colIndex, value: col });
}))
return map.sort(sortFn).map(v => [v.row, v.col]);
}
const interval = setInterval(() => {
console.time("process");
console.log(process(arr))
console.timeEnd("process");
if(--count === 0) clearInterval(interval);
}, 100)
Output:
[
[ 2, 1 ], [ 0, 0 ],
[ 1, 0 ], [ 2, 0 ],
[ 0, 1 ], [ 2, 2 ],
[ 1, 1 ], [ 1, 2 ],
[ 0, 2 ]
]
process: 3.822ms
[
[ 2, 1 ], [ 0, 0 ],
[ 1, 0 ], [ 2, 0 ],
[ 0, 1 ], [ 2, 2 ],
[ 1, 1 ], [ 1, 2 ],
[ 0, 2 ]
]
process: 1.661ms
[
[ 2, 1 ], [ 0, 0 ],
[ 1, 0 ], [ 2, 0 ],
[ 0, 1 ], [ 2, 2 ],
[ 1, 1 ], [ 1, 2 ],
[ 0, 2 ]
]
process: 1.665ms
EDIT 2:
(inspired by another answer with flatMap)
const arr = [
[1, 5, 9],
[2, 7, 8],
[3, 0, 6],
];
const sortFn = (a, b) => a.value === b.value ? 0 : a.value > b.value ? 1 : -1;
arr.flatMap((_row, row) => _row.map((value, col) => { return { row, col, value } })).sort(sortFn).map(v => [v.row, v.col]);
let count = 3;
const process = (arr) => arr.flatMap((_row, row) => _row.map((value, col) => { return { row, col, value } })).sort(sortFn).map(v => [v.row, v.col]);
const interval = setInterval(() => {
console.time("process");
console.log(process(arr))
console.timeEnd("process");
if(--count === 0) clearInterval(interval);
}, 100)
Result:
[
[ 2, 1 ], [ 0, 0 ],
[ 1, 0 ], [ 2, 0 ],
[ 0, 1 ], [ 2, 2 ],
[ 1, 1 ], [ 1, 2 ],
[ 0, 2 ]
]
process: 10.979ms
[
[ 2, 1 ], [ 0, 0 ],
[ 1, 0 ], [ 2, 0 ],
[ 0, 1 ], [ 2, 2 ],
[ 1, 1 ], [ 1, 2 ],
[ 0, 2 ]
]
process: 1.346ms
[
[ 2, 1 ], [ 0, 0 ],
[ 1, 0 ], [ 2, 0 ],
[ 0, 1 ], [ 2, 2 ],
[ 1, 1 ], [ 1, 2 ],
[ 0, 2 ]
]
process: 2.043ms