在Javascript中对2D数组/网格/项目表进行排序

时间:2017-11-14 16:20:13

标签: javascript arrays sorting

我的游戏中有项目清单,玩家需要能够根据名称,数量和类型等多个标准对项目进行自动排序。

Possible Unhandled Promise Rejection (id:0)

然而,我似乎无法弄清楚如何将网格排序为项目表。 我需要它按所选列对行顺序进行排序,并能够按ASC / DESC顺序对其进行排序。我该怎么做呢?

1 个答案:

答案 0 :(得分:1)

要按字母顺序对数组进行排序,只需使用localeCompare方法即可。数字有自己的版本,可能会令人困惑,所以我们在比较之前强制变量。

function sortAlphabetically(a, b) {
    return String(a).localeCompare(b);
}

["cat", "apple", "dog", "beef"].sort(sortAlphabetically);
// -> ["apple", "beef", "cat", "dog"]

我认为您遇到的主要问题实际上与您创建阵列的方式有关。目前,您的阵列看起来像这样:

var inventory = [
    ["Potion", "Elixir", "Antidote", "Ether"],
    [2, 9, 5, 1]
];

这意味着除了数组指示之外,"Potion"2之间没有任何关联。如果您将阵列调整为这样,我认为您会有更好的运气。

var inventory = [
    ["Potion", 2],
    ["Elixir", 9],
    ["Antidote", 5],
    ["Ether", 1]
];

排序更容易。作为奖励,运行.concat()方法将在尝试对数组进行排序之前克隆该数组,以便原始数据不被修改,并且该函数默认以升序返回数据更为常规。

function sort2D(array, byColumn, isDescending) {

    var sorted = array.concat().sort(function (a, b) {

        return typeof a[byColumn] === "string"
            ? sortAlphabetically(a[byColumn], b[byColumn])
            : a[byColumn] - b[byColumn];

    });

    return isDescending
        ? sorted.reverse()
        : sorted;

}

sort2D(inventory, 0);
// -> [ ["Antidote", 5], ["Elixir", 9], ["Ether", 1], ["Potion", 2] ]
sort2D(inventory, 0, true);
// -> [ ["Potion", 2], ["Ether", 1], ["Elixir", 9], ["Antidote", 5] ]
sort2D(inventory, 1);
// -> [ ["Ether", 1], ["Potion", 2], ["Antidote", 5], ["Elixir", 9] ]

我希望有所帮助。

更新的 记录您的信息也变得更容易:

var output = inventory
    .map(function (inv) {
        return "| " + inv.join(" | ") + " |";
    })
    .join("\n");
console.log("| name | own |\n" + output);

更新2: 以下是如何对旧数据进行排序。

function sort2D(array, byColumn, isDescending) {

    // Step 1: sort the part of the array you're trying to sort.

    var preSort = array[byColumn].concat().sort(function (a, b) {

        return typeof a === "string"
            ? sortAlphabetically(a, b)
            : a - b;

    });

    if (isDescending) {
        preSort = preSort.reverse();
    }

    // Step 2: create a new, sorted array with your sorted column.

    var sorted = [];
    sorted[byColumn] = preSort;

    // Step 3: create a map to show how the array way sorted.

    var sortMap = {};
    preSort.forEach(function (item, i) {
        sortMap[array[byColumn].indexOf(item)] = i;
    });

    // Step 4: manually sort the other items of the array.

    array.forEach(function (info, i) {

        var copy = [];

        if (i !== byColumn) {

            info.forEach(function (item, j) {
                copy[sortMap[j]] = item;
            });

            sorted[i] = copy;

        }

    });

    // Step 5: return the newly sorted array.

    return sorted;

}