如何对复杂数值多维Javascript数组进行排序?

问题描述 投票:0回答:1

我必须对这个数组进行排序,

const array = [
  [18, [18, 16], 16],
  15,
  [18, 19, 51],
  [[18, 16], 15, [14, 13]],
  [10, 9, 20],
  99,
  49,
  [11, [22, 10], [[10, 9], 11, 9, [1, 2]], 100, 72],
  [[11], [[19, 14], [77, 18]]]
];

对该数组进行排序,

  1. 该数组中的所有单个元素都排在前面

  2. 之后是一维数组

  3. 之后是二维数组

  4. 之后是三维数组

  5. .....等等

  6. 所有元素都应在所有数组内排序。

结果应该是这样的,

[
  15,
  49,
  99,
  [18, 19, 51],
  [9, 10, 20],
  [16, 18, [16, 18]],
  [15, [16, 18], [13, 14]],
  [11, 72, 100, [10, 22], [9, 11, [9, 10], [1, 2]]],
  [[11], [[14, 19], [18, 77]]]
]

这就是我尝试实现它的方式 - 它最多适用于四维数组,但是如果我们有 n 维数组(n>4),则此代码将不起作用,那么我们如何实现/优化此代码这样我们就可以获得所有n维数组的结果。

const array = [
    [ 18, [18,16], 16], 
    15, 
    [18, 19, 51], 
    [[18, 16], 15, [14, 13]], 
    [10,9,20], 
    99, 
    49, 
    [11, [22,10], [[10,9], 11, 9, [1,2]], 100, 72],
    [[11], [[19, 14], [77, 18]]]
];

function getArrayDepth(value) {
    return Array.isArray(value) ?
        1 + Math.max(0, ...value.map(getArrayDepth)) :
        0;
}

function sort_array1(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[i] > arr[j]) {
                const temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

function sort_array2(arr) {
    for (let j = 0; j < arr.length; j++) {
        arr[j] = sort_array1(arr[j]);
    }

    return arr;
}

function sort_array3(arr) {
    for (let j = 0; j < arr.length; j++) {
        let array1 = [];
        let array2 = [];

        for (let k = 0; k < arr[j].length; k++) {
            if (getArrayDepth(arr[j][k]) == 0) {
                array1.push(arr[j][k]);
            }
            else {
                array2.push(arr[j][k]);
            }
        }

        array1 = sort_array1(array1);
        array2 = sort_array2(array2);
        arr[j] = array1.concat(array2);
    }

    return arr;
}

function sort_array4(arr) {
    for (let j = 0; j < arr.length; j++) {
        let array1 = [];
        let array2 = [];
        let array3 = [];

        for (let k = 0; k < arr[j].length; k++) {
            if (getArrayDepth(arr[j][k]) == 0) {
                array1.push(arr[j][k]);
            }
            else if (getArrayDepth(arr[j][k]) == 1) {
                array2.push(arr[j][k]);
            }
            else {
                array3.push(arr[j][k]);
            }
        }

        array1 = sort_array1(array1);
        array2 = sort_array2(array2);
        array3 = sort_array3(array3);
        arr[j] = array1.concat(array2, array3);
    }

    return arr;
}

function sequenced_array(arr) {
    let array1 = [];
    let array2 = [];
    let array3 = [];
    let array4 = [];

    for (let i = 0; i < arr.length; i++) {
        if (getArrayDepth(arr[i]) == 0) {
            array1.push(arr[i]);
        }
        else if (getArrayDepth(arr[i]) == 1) {
            array2.push(arr[i]);
        }
        else if (getArrayDepth(arr[i]) == 2) {
            array3.push(arr[i]);
        }
        else {
            array4.push(arr[i]);
        }
    }

    array1 = sort_array1(array1);
    array2 = sort_array2(array2);
    array3 = sort_array3(array3);
    array4 = sort_array4(array4);

    array1 = array1.concat(array2, array3, array4);
    return array1;
}

let sortedArray = sequenced_array(array);

/*for (let i = 0; i < sortedArray.length; i++) {
    console.log(sortedArray[i]);
}*/

console.log(sortedArray)

javascript arrays multidimensional-array
1个回答
0
投票

注意:自定义排序相当繁重。这些都具有时间和空间复杂度,对于非常大和/或很深的数组来说可能是令人望而却步的。

也许其他人可能会给出更好的解决方案

const getDepth = (item) => !Array.isArray(item) ? 0 : 1 + Math.max(...item.map(getDepth), 0);

const customSort = (a, b) =>  {
  const depthA = getDepth(a);
  const depthB = getDepth(b);
  if (depthA !== depthB) return depthA - depthB;
  if (Array.isArray(a) && Array.isArray(b)) {
    for (let i = 0; i < Math.min(a.length, b.length); i++) {
      const comp = customSort(a[i], b[i]);
      if (comp !== 0) return comp;
    }
    return a.length - b.length;
  }
  if (!Array.isArray(a) && !Array.isArray(b)) return a - b;
  return Array.isArray(a) ? 1 : -1;
}

const sortArray = (array) => {
  // only sort arrays
  if (!Array.isArray(array)) return array;

  // recursively sort arrays
  const deeplySorted = array.map(item => Array.isArray(item) ? sortArray(item) : item);

  // Then, sort by depth and value
  return deeplySorted.sort(customSort);
}

console.log(sortArray(array));
<script>
const array = [
    [18, [18, 16], 16],
    15,
    [18, 19, 51],
    [[18, 16], 15, [14, 13]],
    [10, 9, 20],
    99,
    49,
    [11, [22, 10], [[10, 9], 11, 9, [1, 2]], 100, 72],
    [[11], [[19, 14], [77, 18]]],
    [[[[3],[2],[2,3,1]]]] // Added this deeply nested array
];
</script>

© www.soinside.com 2019 - 2024. All rights reserved.