有没有一种简单的方法来创建一个JavaScript查找表?

16

我正在寻找一种简单的方式,使用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中实现这个目标的简便方法。


为什么要用jQuery而不是简单的js?只是问一下... - Yoshi
简单的JS也可以运行... :) 今天过得很长啊。 - Paul
为什么你想要使用jQuery来做这件事?一个更简单的方法是使用多维JavaScript数组。 - Rory McCrossan
当你传递1 2 3时,如何得到45?此外,你尝试过什么,遇到了什么问题? - Fahim Parkar
我认为我们需要更多地了解数据。您是否拥有所有小于X的A、B、C值的查找值?如果是这样,那么您可以使用三维数组:var answer = data[1][2][3];answer = data[2][2][3];。当然,您必须使用正确的数据填充这个三维数组。 - jfriend00
A、B和C的值不是线性的,所以A可能有1、45、89等值……这对3D数组仍然有效吗? - Paul
4个回答

13

在页面加载时,您可以使用可工作的fiddle将价格索引到二维地图中。

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) 初始化选择器(填充值和事件“change”):

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)在选择更改时更新span函数:

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);

仅显示 'Blue' 和 'Small' 的价格:

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

1
谢谢。请注意,此行有拼写错误 >> 'Medium, << - ปรีดา ตั้งนภากร
不会说这很“简单”,但还是谢谢,相当正宗。 - Motassem Kassab

9
最常见的解决方案是以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工具包中的此代码


笔误?matches_filter还是matched_filter? - Jeremy Odekirk
谢谢。下次如果您看到这样的内容,请随意提供建议。 - hugomg
通常情况下,小的拼写错误无法作为编辑提交(更改不够)。 - worc

8
这可能是什么?
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

A、B和C的值不是线性的,所以A可能有1、45、89等值……这对于这个解决方案仍然有效吗?(这是我考虑过的,但可能过度思考了我所写的内容) - Paul
@Paul 当然可以。我只是使用对象字面量符号构建一个对象。你可以使用任何你想要的。也许你可以添加更多的数据,这样我们就可以更好地理解你想要实现什么。 - Yoshi
这基本上就是我的数据,每个记录有3个键值对,我正在尝试通过传入3个键值对(每列一个)来定位该表中的记录... 我认为我遇到的最大问题是列的顺序... 我不一定知道它,虽然可能可以重新排列我传入的内容。 - Paul
@Paul 我仍然无法清楚地看到你的输入数据以及你在javascript中尝试访问它的方式。你能否加入一些示例? - Yoshi
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/7045/discussion-between-paul-and-yoshi - Paul
显示剩余2条评论

1
由于颜色和大小代表价格,我们可以创建一个枚举分别为颜色和大小,通过以下方式提供索引值:
const color = {
  BLUE: 0,
  RED: 1    
}
const size = {
  SMALL : 0,
  LARGE : 1
}

Value assignments:

var prices[10][2];

prices[color.BLUE][size.SMALL] = 40;
prices[color.BLUE][size.LARGE] = 80;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接