Related
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
I'm a student who has just studied javaScript.
I'm trying to solve an algorithm problem, but I can't solve the problem.
just simple Q ... but I couldn't solve the problem.
[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
please advice me How should make it what I want array
I need to turn a 2D array into a 1D array.
result i want [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ]
I've tried to do many thing.
At first I thought it would be easy , but I couldn't.
I tried many methods, but I didn't get the result.
let a = [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
a.toString().split('').join('')
let result = [];
result.push(a) // [ '1,2', '1,3', '2,1', '2,3' ] // string
How can I get the results [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ]?
This is the closest result I get :
let a = [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
let res = '';
a.forEach(b => {
res += `[${b}],`
});
console.log(res); // [1,2],[1,3],[2,1],[2,3],[3,1],[3,2],
I hope I helped !
Update
To answer OP from the comments below :
let a = [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3,2 ] ]
let res = a.map(cell => cell = +cell.join(''))
console.log(res); // [12, 13, 21, 23, 31, 32]
.map() : see the MDN docs here
On the first call cell will be [ 1, 2 ]. Using .join('') on it will result in "12". Having a + sign before the .join('') call will parse the result in number.
I hope I explained the process well :)
I am trying to understand what you mean here, but i believe what you want is this
let a = [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ];
let arr = [];
for (i=0;i<a.length;++i){
var toTXT = a[i][0]+","+a[i][1];
arr[i] = toTXT;
}
console.log(arr) // (6) ['1,2', '1,3', '2,1', '2,3', '3,1', '3,2']
const arr = [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ];
let newArr = [];
for(let a of arr){
for(let b of a){
newArr.push(b);
}
}
console.log( newArr ); // this is 1 dimensional array.
/*
your request :
[ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ]
that was an invalid sintax. you cant.
the valid one is :
[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ];
*/
So I have this 2D permutations array of ints which looks like this:
arr = [
[ 5, 2, 6 ],
[ 2, 5, 6 ],
[ 6, 5, 2 ],
[ 5, 6, 2 ],
[ 2, 6, 5 ],
[ 6, 2, 5 ]
]
and essentially I want to be able to get a string that looks like this '652,625,562,526,256'
This means that the numbers are ordered and are in string format.
What I have done so far is:
arr.map(c => c.join("")).join()
Which combines it to a array, however now my thought process would be to convert this to a array of ints and then order and re-parse as strings, but there must be some kind of easier way to do this?
I'm quite new to JavaScript so any help is appreciated.
Don't do the second join immediately - instead, sort the array of joined strings first, then join:
const arr = [
[ 5, 2, 6 ],
[ 2, 5, 6 ],
[ 6, 5, 2 ],
[ 5, 6, 2 ],
[ 2, 6, 5 ],
[ 6, 2, 5 ]
];
const result = arr
.map(subarr => subarr.join(''))
.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }))
.join();
console.log(result);
or map to numbers and subtract in the comparator:
const arr = [
[ 5, 2, 6 ],
[ 2, 5, 6 ],
[ 6, 5, 2 ],
[ 5, 6, 2 ],
[ 2, 6, 5 ],
[ 6, 2, 5 ]
];
const result = arr
.map(subarr => Number(subarr.join('')))
.sort((a, b) => b - a)
.join();
console.log(result);
I am trying to convert a function of python code into JavaScript.
The arr variable is an array such as [2, 5, 3, 1]. Basically, I want to create a list of tuple where each tuple contains as first value the position of the element in the arr and as second value the element of the arr. Then, I want to do the same for the reversed of arr
Python code:
def myPositions(arr):
positions = sorted(list(enumerate(arr)), key=lambda e: e[1])
return positions
def final(arr):
print("Reversed", arr[::-1]) # [ 1, 3, 5, 2 ]
print(myPositions(arr)) # [(3, 1), (0, 2), (2, 3), (1, 5)]
print(myPositions(arr[::-1])) # [(0, 1), (3, 2), (1, 3), (2, 5)]
My JavaScript code
Since there is no enumerate in JavaScript (this is what I think), I did the following:
function myPositions(arr) {
let positions = arr.map((e,i) => [i, e]).sort((a, b) => a[1] - b[1] )
return positions
}
function final(arr) {
let reversedArr = arr.reverse()
console.log("Reversed", reversedArr) // [ 1, 3, 5, 2 ]
let x = myPositions(arr)
console.log(x) // [ [ 0, 1 ], [ 3, 2 ], [ 1, 3 ], [ 2, 5 ] ]
let y = myPositions(reversedArr)
console.log(y) // [ [ 0, 1 ], [ 3, 2 ], [ 1, 3 ], [ 2, 5 ] ] This is different than print(myPositions(arr[::-1]))
}
I do not get why it works the same if I do not reverse the array.
But with the reversed array, I get two different results.
In python I get [(0, 1), (3, 2), (1, 3), (2, 5)], in JS I get [ [ 0, 1 ], [ 3, 2 ], [ 1, 3 ], [ 2, 5 ] ]
I have an array with objects
const nodes = [ { children: [1, 2, 3] }, { children: [1, 2, 3] } ];
I want a new array [ 1, 2, 3, 1, 2, 3 ].
I have tried
nodes.map(node => node.children);
but it gives me [ [ 1, 2, 3 ], [ 1, 2, 3 ] ].
I have tried
[].concat(nodes.map(node => node.children));
but it doesn't work since it is just concatenating [] with [ [ 1, 2, 3 ], [ 1, 2, 3 ] ] which is just [ [ 1, 2, 3 ], [ 1, 2, 3 ] ].
You could use Array#reduce
const nodes = [ { children: [1, 2, 3] }, { children: [1, 2, 3] } ],
result = nodes.reduce((r, node) => r.concat(node.children), []);
console.log(result);
console.log([... new Set(result)]); // for unique values
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this with Array#reduce
const nodes = [ { children: [1, 2, 3] }, { children: [1, 2, 3] } ];
var result = nodes.reduce(function(r, o) {
r = r.concat(o.children);
return r;
}, []);
console.log(result)
Another way to do this using Array#forEach:
const nodes = [ { children: [1, 2, 3] }, { children: [1, 2, 3] } ]
final = []
nodes.forEach(x => final = final.concat(x.children))
console.log(final)
Another shorter way is (a little modification to what OP was trying to do):
const nodes = [ { children: [1, 2, 3] }, { children: [1, 2, 3] } ];
var result = [].concat.apply([], nodes.map(x => x.children))
console.log(result);