Array.indexOf 列表列表不起作用

Array.indexOf for list of lists is not working

我有一个列表列表,它来自 ajax response 中的服务器,具有以下结构:

var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],

    ["personOne", 1],
    ["personTwo", 2],
    ["personOne", 3],
];

因为列表永远不变,任何时候都只有 7 个元素。我想要它的任何元素的索引来更新一些 DOM 元素。

// Gives me any of list element which is random elm of the list `mapping`.
var captured_list_elm =  process_mapping_list();     
var status = mapping.indexOf(captured_list_elm);// getting always -1

在这里,我总是 -1 获取状态。

创建了 jsFiddle

注意 - 实际上它应该是 json 但我们团队中的某个人将其写为列表列表。我现在无法更新它,因为代码正在生产中。

Array.indexOf() 使用严格相等 (===) 来查找元素。 mapping 的元素是数组,而恰好具有相同元素的两个不同数组不是 ===。我怀疑 process_mapping_list() 正在返回一个数组 看起来 mapping 的元素之一但不是元素本身(就像你的 fiddle确实)。

您可能需要编写自己的使用自定义相等性测试的查找函数。对于这样的测试,请查看 this thread. Depending on the environment(s) you are targeting, you may be able to use findIndex() 而不是 indexOf()。该函数允许您提供自己的测试函数。

这是解决 === indexOf 问题的方法...

选项 1:

.

 var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],

    ["personOne", 1],
    ["personTwo", 2],
    ["personOne", 3],
 ];

 var jsonMapping = [];
 for (var i = 0; i < mapping.length; i++) {
    jsonMapping.push(JSON.stringify(mapping[i]));
 }
 var captured_list_elm = ["personOne", 1];
 var status = jsonMapping.indexOf(JSON.stringify(captured_list_elm));
 alert("status= "+status);

选项 2

.

var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],

    ["personOne", 1],
    ["personTwo", 2],
    ["personOne", 3],
];
var findIndex = function (hayStack, needle) {
    for (var i = 0; i < hayStack.length; i++) {
        if(hayStack[i][0] === needle[0] && hayStack[i][1] === needle[1]) {
            return i;
        }
    }
    return -1;
};
var captured_list_elm = ["personOne", 1];
var status = findIndex(mapping, captured_list_elm);
alert("status= "+status);

为了确认@ted-hopp 给出的答案,我分叉了你的 JSFiddle 并 slightly modified 它。基本上我所做的是将变量 captured_list_elm 移动到顶部并将其作为值添加到数组中。正如您现在看到的 Array.indexOf returns 4 这是正确的(从零开始)索引:

var captured_list_elm = ["personOne", 1];

var mapping = [     //response.mapping
    ["userOne", 1],
    ["userTwo", 2],
    ["userthree", 3],
    ["userfour", 4],
    captured_list_elm,
    ["personTwo", 2],
    ["personOne", 3],
];

var status = mapping.indexOf(captured_list_elm);
alert("status= "+status);

您可能需要做的是添加一个 for 循环来遍历您的数组并比较值。

问题是您正在使用 indexOf 比较两个数组。如果您 运行 您的 jsFiddle 使用此代码,它将 return 正确的索引,因为它比较的是数组本身,而不是数组中的元素。

var status = mapping.indexOf(mapping[6]);