web-dev-qa-db-ja.com

javascriptルックアップテーブルを作成する簡単な方法はありますか?

Javascriptを使用して、いくつかのディメンションに対して値を検索する簡単な方法を探しています。

例えば。 (これを説明するために製品と製品オプションを使用します。データは非常によく似た形式でデータベースから取得されます)

Colour  Size Price

Blue    S    £45

Blue    L    £98

Red     S    £65

Red     L    £31

だから私はページにいくつかのドロップダウンがあります

Colour: Blue, Red

Size:   Small, Large

だから-知りたい...「ブルー+スモール」の場合、価格はいくらですか

ドロップダウンの順序や、データベースから色とサイズが取得される順序がわかりません。

Javascriptのデータは、次のような配列になります。

{Colour:Blue, Size:Medium, Price:48},{Colour:Blue, Size:Large, Price:82}

これは大雑把な例ですが、JavaScriptでこれを実現する簡単な方法を見つけることはできません。

12
Paul

ページの読み込み時に2次元マップで価格にインデックスを付けることができます(動作中 フィドル )。

1)選択値をプリロードする必要がある場合に備えて、ルックアップテーブルに選択値を配置します。

var tables = {
    Colour: ["Blue", "Red"],
    Size: ["Small", "Medium", "Large"]
};

2)配列形式の価格表は次のとおりです。

var array = [
    {Colour: "Blue", Size: "Small", Price: 45},
    {Colour: "Blue", Size: "Medium", Price: 48},
    {Colour: "Blue", Size: "Large", Price: 98},
    {Colour: "Red", Size: "Small", Price: 65},
    {Colour: "Red", Size: "Large", Price: 31}
];

3)選択の初期化(値の入力とイベント '変更'):

for (var key in tables)
    if (tables.hasOwnProperty(key)) {
        selects[key] = form[key];
        selects[key].addEventListener("change", updateSpan);

        var values = tables[key];
        len = values.length;
        for (i = 0; i < len; i++) {
            var option = document.createElement('option');
            option.appendChild(document.createTextNode(values[i]));
            form[key].appendChild(option);
        }
    }

4)価格表のインデックス作成:

len = array.length;
for (i = 0; i < len; i++) {
    var record = array[i];

    if (typeof map[record.Colour] === 'undefined')
        map[record.Colour] = {};

    map[record.Colour][record.Size] = record.Price;
}

5)関数updateSpan(選択変更時):

function updateSpan() {
    var Colour = selects.Colour.options[selects.Colour.selectedIndex].value;
    var Size = selects.Size.options[selects.Size.selectedIndex].value;

    if (typeof map[Colour] !== 'undefined' && typeof map[Colour][Size] !== 'undefined')
        span.textContent = map[Colour][Size];
    else
        span.textContent = "Price not defined to Colour: " + Colour + " and Size: " + Size + ".";
}

6)デバッグ(ChromeまたはFirefoxでF12を押してコンソールビューを開きます)。

完全なインデックス付きテーブル:

console.log(map);

「ブルー」と「スモール」の価格だけ:

console.log(map['Blue']['Small']); // outputs the value: 45

これは多分?

var data = {
  1: {
    2: {
      3: 45
    }
  },
  2: {
    2: {
      3: 98
    }
  }
};

console.log(data[1][2][3]); // 45
console.log(data[2][2][3]); // 98

// or
var A = 1, B = 2, C = 3;
console.log(data[A][B][C]); // still 45
7
Yoshi

これに対する最も一般的な解決策は、O(N)スタイルで配列をループすることです。

var filter = {Colour: 'blue', Size:'small'};
function matches_filter(filter, item){
    //you can also have variations on this function that
    //allow for functions, regexes or anything you like in the filter...
    for(var key in filter){
        if Object.prototype.hasOwnProperty.call(filter, key){
            if(item[key] !== filter[key]){
                return false;
            }
        }
    }
    return true;
}

var filtered_items = [];
for(var i=0; i<items.length; i++){
    var item = items[i];
    if(matches_filter(filter, item)){
        filtered_items.Push(item);
    }
}

総当たり攻撃の背後にある理由は、より優れたアルゴリズムを必要とするほど大きなデータセットがある場合は、クエリをサーバーに返送してデータベースにハードワークを実行させるのが最善である可能性が高いということです。あなたのために。

より完全な例については、Dojoツールキットから このコード を確認できます。

6
hugomg