简体   繁体   English

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

[英]Sort a 2D Array/Grid/Table of items in Javascript

I have an inventory of items in my game and the player will need to have the ability to auto-sort the items based on several criteria being name,quantity and type. 我有一个游戏中的物品清单,玩家需要能够根据名称,数量和类型等几个标准对物品进行自动分类。

 // create the Inventory grid var InventoryWidth = 2; var InventoryHeight = 4; var Inventory = new Array(InventoryWidth); for (var i = 0; i < InventoryWidth; i++) { Inventory[i] = new Array(InventoryHeight); } // set the Items & default quantities Inventory[0][0] = "Potion"; Inventory[1][0] = 2; Inventory[0][1] = "Elixir"; Inventory[1][1] = 9; Inventory[0][2] = "Antidote"; Inventory[1][2] = 5; Inventory[0][3] = "Ether"; Inventory[1][3] = 1; // function for sorting items function Sort2D(array2D, byColumn, ascending) { // sort, seems I am using the wrong sorting function or my approach is wrong here: // not sure how to do ASC/DESC as well array2D.sort(function(a, b) { if(a[0] === b[0]) { var x = a[byColumn].toLowerCase(), y = b[byColumn].toLowerCase(); return x < y ? -1 : x > y ? 1 : 0; } return a[0] - b[0]; }); } // sort all rows by first column: "name", setting to 1 should compare and sort the quantities instead Sort2D( Inventory, 0, true); // print grid contents var output = ""; for(var i = 0; i < InventoryHeight; i++) { if (i == 0) { output += " | name | own |"; } for(var j = 0; j < InventoryWidth; j++) { if (j == 0) { output += "\\n"+i+"|"; } output+=Inventory[j][i]; if (j >= Inventory[0].length-1) { output += "|\\n"; } else { output += ", "; } } } console.log(output); 

However I can't seem to figure out how to sort the grid like a table of items. 但是,我似乎无法弄清楚如何像项目表一样对网格进行排序。 I'd need it to sort the row order by a chosen column and the ability to have it in ASC/DESC order. 我需要它按选定列对行顺序进行排序,并具有按ASC / DESC顺序对其进行排序的功能。 How would I go about this? 我将如何处理?

To sort an array alphabetically, you just need to use the localeCompare method. 要按字母顺序对数组排序,您只需要使用localeCompare方法。 Numbers have their own version and that can be confusing, so we coerce the variable before comparing it. 数字有其自己的版本,可能会造成混淆,因此我们在比较变量之前将其强制转换。

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

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

I think the main problem you're having is actually with the way you've created your array. 我认为您遇到的主要问题实际上是创建数组的方式。 At the moment, your array looks like this: 此刻,您的数组如下所示:

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

That means there's no association between "Potion" and 2 , other than the array indicies. 这意味着"Potion"2之间没有关联,除了数组索引。 I think you'll have much better luck if you adjust the array to look like this. 我认为,如果您将数组调整为这样,您的运气会更好。

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

Sorting that is much easier. 排序要容易得多。 As a bonus, running the .concat() method will clone the array before trying to sort it so the original data isn't modified and having the function return the data in ascending order by default is more conventional. 另外,运行.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] ]

I hope that helps. 希望对您有所帮助。

Update: Logging out your information becomes easier as well: 更新:注销您的信息也变得更加容易:

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

Update 2: Here's how to sort the old data. 更新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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM