2017-11-14 4 views
0

私は自分のゲーム内のアイテムの目録を持っています。プレイヤーは名前、数量、タイプといういくつかの基準に基づいてアイテムを自動ソートする必要があります。私はアイテムの表のようにグリッドをソートする方法を見つけ出すように見えることはできませんしかしJavascriptでアイテムの2D配列/グリッド/テーブルを並べ替えます。

// create the Inventory grid 
 
var InventoryWidth = 2; 
 
var InventoryHeight = 4; 
 

 
var Inventory = new Array(InventoryWidth); 
 
for (var i = 0; i < InventoryWidth; i++) { 
 
\t Inventory[i] = new Array(InventoryHeight); 
 
} 
 

 

 
// set the Items & default quantities 
 
Inventory[0][0] = "Potion"; 
 
\t Inventory[1][0] = 2; 
 
\t 
 
Inventory[0][1] = "Elixir"; 
 
\t Inventory[1][1] = 9; 
 
\t 
 
Inventory[0][2] = "Antidote"; 
 
\t Inventory[1][2] = 5; 
 

 
Inventory[0][3] = "Ether"; 
 
\t Inventory[1][3] = 1; 
 
\t 
 
// function for sorting items 
 
function Sort2D(array2D, byColumn, ascending) { 
 

 
\t // sort, seems I am using the wrong sorting function or my approach is wrong here: 
 
    // not sure how to do ASC/DESC as well 
 
\t array2D.sort(function(a, b) 
 
\t { 
 
\t \t if(a[0] === b[0]) 
 
\t \t { 
 
\t \t \t var x = a[byColumn].toLowerCase(), y = b[byColumn].toLowerCase(); 
 
\t \t \t 
 
\t \t \t return x < y ? -1 : x > y ? 1 : 0; 
 
\t \t } 
 
\t \t return a[0] - b[0]; 
 
\t }); 
 

 
} 
 

 
// 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++) { 
 
\t 
 
    if (i == 0) { 
 
     output += " | name | own |"; 
 
    } 
 
    
 
\t for(var j = 0; j < InventoryWidth; j++) { 
 
\t \t 
 
\t \t if (j == 0) { 
 
\t \t \t output += "\n"+i+"|"; 
 
\t \t } 
 
\t \t 
 
\t \t output+=Inventory[j][i]; 
 
\t \t 
 
\t \t if (j >= Inventory[0].length-1) { 
 
\t \t \t output += "|\n"; 
 
\t \t } else { 
 
\t \t \t output += ", "; 
 
\t \t } 
 
\t } 
 
} 
 
console.log(output);

。 私はそれを選択された列とASC/DESCの順序でそれを持つ能力によって行の順序をソートする必要があります。私はこれについてどうやって行くのですか?

答えて

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; 

} 
+0

これはうまくいくようですが、このような配列構造を変更するとarray2dクラス全体が混乱するため、周囲のセルを反転させるようです。私は間違っていますか?これをリファクタリングすることは、この時点では大変な作業です。 あなたの方法で、私はそのようなアイテムを割り当てようとしました インベントリ[0、0] = "ポーション"; インベントリ[1、0] = 2; インベントリ[0、1] = "エリキシル"; インベントリ[1,1] = 9; インベントリ[0、2] = "解毒剤"; インベントリ[1、2] = 5; これはうまくいかなかったようですが、inventory.map関数は "inv"が何であるかわからないようでしたが、その関数の使い方はわかりません – user780756

+0

リファクタリングをお勧めします。あなたのデータをそのままソートすることは可能ですが、より多くのステップがありますので、エラーが発生しやすくなります。 '.push()'、 '.splice()'や '.sort()'のような変更によって配列インデックスを失うことも非常に簡単です。あなたの配列にアイテムを割り当てることは、 'Inventory [0、1]'で行うことはできません。 'Inventory [0] [1]'が必要です。JavaScriptは大文字と小文字を区別しています。私の答えを見ると、 'Inventory'に小文字のIを付けました。おそらく' Inventory.map() 'はもっと成功するでしょう:) –

関連する問題