Sorting an array of arrays of integers - javascript

I have a variable dimensions, which contains the maximum size of each element of an array, e.g.:
const dimensions = [10, 6, 4]
I also have an array of arrays containing as many integers as the size of the dimensions array, e.g.:
let boxes = [
[1, 2, 1],
[10, 2, 4],
[4, 1, 1],
[10, 2, 3]
]
For every array in boxes, no element will be higher than its counterpart in dimensions.
I want to find a way to sort these arrays, so that the sorted array boxes would be:
[
[1, 2, 1],
[4, 1, 1],
[10, 2, 3],
[10, 2, 4]
]
As you see, it's not just about sorting by the array's first element. It's sorting by first element, and if they're equal, the second, etc.
For each array of arrays, I have a related dimensions variable. But dimensions can be anything (also any length!) (and consequently, the arrays will have the same length of course).
I'm doing this in Javascript, but pseudocode is welcome too.
PS - This is not part of an assignment, I tried to abstract away most of the unnecessary stuff.

You can sort the values using Array.reduce to compare the values in each array being sorted, only updating the comparison result if it is currently 0 (i.e. the values up to now have been equal):
let boxes = [
[1, 2, 1],
[10, 2, 4],
[4, 1, 1],
[10, 2, 3]
]
boxes.sort((a, b) => a.reduce((c, v, i) => c ? c : v - b[i], 0));
console.log(boxes);

Related

How to get numbers out of a 2D array to a 1D array [duplicate]

This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed last year.
I have an argument that passes me a 2D array and I want to get the numbers from that array and put them on a normal array.
The argument passed to me = ([1, 3, 2], [5, 2, 1, 4], [2, 1])
What I want to do = [1, 3, 2, 5, 2, 1, 4, 2, 1]
Thanks in advance, I think I'm having a brain fart over here!
You can use the flat method of Array!
const arr = [[1, 2, 3], [4, 5, 6]]
console.log(arr.flat())
// [1, 2, 3, 4, 5, 6]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
Iterate the array and add all data in new array with concat() method.
var arr = [[1, 3, 2], [5, 2, 1, 4], [2, 1]];
var newArr = [];
for(var i = 0; i < arr.length; i++)
{
newArr = newArr.concat(arr[i]);
}
console.log(newArr);
You can use array flat method to convert 2d array to 1d array
const arr = [
[1,2,3],
[4,5,6]
].flat(1); //flat(depth:Number)
console.log(arr);
// [1,2,3,4,5,6]

JS Reduce: sum specific position in a nested array of numbers

I want to reduce only a specific position in a nested number array
const array1 = [[1,2,3],[4,5,6],[7,8,9],[11,12,13]];
console.log(array1.reduce((prev, curr) => prev[2] + curr[2]));
The result is NaN, another solution?
1) You should use prev not prev[2] as
prev is of type number that you are returning not an array
2) If you are adding the number then it is better to take initial value as 0 as a second argument to the reduce method.
If you won't pass second argument, then reduce will take the array element at 0 index as the starting value i.e [1, 2, 3] and then if you add [1, 2, 3] + curr[2] then it will produce value as 1,2,36, which you are not expecting
const array1 = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[11, 12, 13],
];
console.log(array1.reduce((prev, curr) => prev + curr[2], 0));

Sorting two arrays according specific order

What I'm trying to do is ordering 2 arrays lets say...
let C = [10, 5, 6, 7]
let M = [8, 9, 2, 5]
The first array should stay as it is, but the second needs to be orderer so the output should go like this
[10, 5, 6, 7]
[9, 2, 5, 8]
Basically, i need to order the second array so that the max value matches the max value of the other array.
Please take into account that the first array should stay the same, so i cant reorder both, just the second
To clarify, each array item is a box with that amount of coins and multipliers. One array is coins and the other multipliers.
You can't change the position of the coin boxes, but you can move the multiplier so you can get the max amount of coins. But you can't move the coin boxes from their position.
What i've discover is that in order to get the max amount of coins, you need to multiply the highest possible value, with the highest posible value of the other table. so te correct order would be something like
[1,3,2,4]
[5,7,6,8]
and the values in example are
[5 3 7 1]
[1 4 3 9]
//expected output
[4 3 9 1]
You need to correlate the two arrays by matching the highest number from C to the highest at M, and so on until the smallest.
To do so create a new array of indexes (order), map arr1, add the index to each item, an then sort the array (I chose descending order).
Now clone arr2 and sort it in the same sort order you've used for C (descending order) to get the sorted array.
Now reduce the order array to another array, take the item with the same index i from sorted, and put it in the index idx taken from the order array.
const fn = (arr1, arr2) => {
const order = arr1
.map((n, i) => [n, i])
.sort(([n1], [n2]) => n2 - n1)
.map(([, i]) => i)
const sorted = [...arr2].sort((n1, n2) => n2 - n1)
return order.reduce((acc, idx, i) => (acc[idx] = sorted[i], acc), [])
}
console.log(JSON.stringify(fn(
[10, 5, 6, 7],
[8, 9, 2, 5]
))) // [9, 2, 5, 8]
// [2,0,1,3]
console.log(JSON.stringify(fn(
[5, 3, 7, 1],
[1, 4, 3, 9]
))) // [4, 3, 9, 1]
console.log(JSON.stringify(fn(
[5, 4],
[7, 2]
))) // [7, 2]
console.log(JSON.stringify(fn(
[11, 17, 39],
[7, 5, 3]
))) // [3, 5, 7]

How does a recursive call work in the function?

The purpose of this algorithm is to return an array which is split into smaller two-dimensional arrays inside of it. The length of each internal array is defined by size.
How does the recursive call with .slice() method work here?
How does it make the function return an array split into smaller sub-arrays?
I can't understand this solution.
function chunkyArrayInGroups(arr, size){
if(arr.length <= size){
return [arr];
} else {
return [arr.slice(0, size)].concat(chunkyArrayInGroups(arr.slice(size), size));
}
}
When going up the callstack, chunks get sliced away from the arrays front (.slice(size)):
[0, 1, 2, 3, 4, 5] -> [2, 3, 4, 5] -> [4, 5] -> []
Now at every recursive call there exists an intermediate value holding the sliced away part (.slice(0, size)):
[0, 1] [2, 3] [4, 5]
Now the chunked away parts get concatenated together when the stack unwinds:
[0, 1] [2, 3] [[4, 5]]
[0, 1] [[2, 3], [4, 5]]
[[0, 1], [2, 3], [4, 5]]

Is there a more concise way to remove an entry from an array with lodash?

Below are several stabs at removing 3 from the array [8,2,3,4] using lodash. The elegant syntax for removing an object from an array of objects makes me wonder if I just haven't figured out the right approach here.
> _.remove([8,2,3,4], 3)
[]
> x = [8,2,3,4]
[8, 2, 3, 4]
> _.remove(x, 3)
[]
> x
[8, 2, 3, 4]
> _.remove(x, {3: true})
[]
> x
[8, 2, 3, 4]
> _.remove(x, [3])
[]
> x
[8, 2, 3, 4]
> _.remove(x, function(val) { return val === 3; });
[3]
> x
[8, 2, 4]
Is there another way to remove a matching element from an array that would be similar to _.remove(arrayOfObjs, {id:3})
Yes, but not using remove. You can instead use pull to remove values from an array:
Removes all provided values from array using SameValueZero for equality comparisons.
// pull modifies its argument:
x = [8, 2, 3, 4]
_.pull(x, 3)
x // => [8, 2, 4]
// pull also returns the modified array:
y = _.pull([1, 2, 3, 4, 5], 2, 3) // => [1, 4, 5]

Categories

Resources