1

I want to sort a 2 dimensional array of integers. What is the simplest and most readable way to achieve this?

input:

[
    [3,4,2],
    [5,1,3],
    [2,6,1],
]

output:

[
    [1,1,2],
    [2,3,3],
    [4,5,6]
]
2
  • 2
    Flatten it, sort it, chunk it. Commented Jan 22, 2022 at 18:09
  • 1
    Interesting problem, but what would the purpose be? Where would sorting a matrix be solution relevant? Commented Jan 22, 2022 at 18:27

3 Answers 3

3

If you'd need the deeper arrays to be in order as well, I'd tackel it like so:

  1. Flatten the arrays using flat(), so get just a regular list

    input.flat()
    
  2. Sort them using a custom integer sort function

    .sort((a, b) => a - b)
    
  3. Re-create the second dimension

    array_chunks(sortedArray, 3);
    

    (Function used taken from this answer)


const input = [
    [3,4,2],
    [5,1,3],
    [2,6,1],
];
const array_chunks = (array, chunk_size) => Array(Math.ceil(array.length / chunk_size)).fill().map((_, index) => index * chunk_size).map(begin => array.slice(begin, begin + chunk_size));

let result = array_chunks(input.flat().sort((a, b) => a - b), 3);
console.log(result);

[
  [ 1, 1, 2 ], 
  [ 2, 3, 3 ], 
  [ 4, 5, 6 ]
]
Sign up to request clarification or add additional context in comments.

1 Comment

You need a numeric sort. It's working here only because all are single digits
1

When working with nested arrays, its common to work from the inner most level and then step out. Using this method, we start with the inner arrays:

// Sorting the inner most array
var result = [];
[
  [3,4,2],
  [5,1,3],
  [2,6,1],
].forEach(function(row) {  // a for loop could work as well, this is just shorter.
  result.push(row.sort(function(a, b) {
    return a-b; // ascending 
    // return b-a; // descending 
  }));
});

Then, you sort the outer array. You cannot sort the outer array as a single number, so its necessary to decide on a method. Examples being: average of the array, lowest value, or highest value.

// Using the first value to sort the outer array.
[
  [2,3,4],
  [1,3,5],
  [1,2,6],
].sort(function(a, b) {
  return a[0]-b[0];
});

Alternatively

The wanted output "[[1,1,2],[2,3,3],[4,5,6]]" disregards the inner arrays so it doesn't seem practical. To do this however, we'd reconstruct all inner arrays into one, sort, and then rebuild a nested array assuming each new array is to have 3 values.

  var oneDimensionalArray = [];
  var finalArray = [];
  [
    [3,4,2],
    [5,1,3],
    [2,6,1],
  ].forEach(function(row) {
    oneDimensionalArray = oneDimensionalArray.concat(row);
  });
  oneDimensionalArray.sort();
  for (var i=0; i<oneDimensionalArray.length; i++) {
    if (i%3==0) {
      temp = [];
    } 
    temp.push(oneDimensionalArray[i]);
    if (i%3==2) {  // 3 per line (0-2)
      finalArray.push(temp);
    }
  }

Again, I don't see this having practical usefulness. It would be easier to leave them as a regular array or start with a different setup if all the data is to be used in a way that disregards grouping/array.

Comments

0

This is a general approach of nested array, which could have more nested arrays or different lengths.

It works by taking an array of indices to every value, a flat array of values and finally by assigning all values back to their place.

const
    getIndices = (value, index) => Array.isArray(value)
        ? value.flatMap(getIndices).map(array => [index, ...array])
        : [[index]],
    setValue = (array, keys, value) => {
        const last = keys.pop();
        keys.reduce((a, i) => a[i] ??= [], array)[last] = value;
        return array;
    }; 
    data = [[3, 4, 2], [5, 1, 3], [2, 6, 1]],
    references = data.flatMap(getIndices),
    result = data
        .flat()
        .sort((a, b) => a - b)
        .reduce((r, v, i) => setValue(r, references[i], v), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.