4

什么是在数组中查找项目的最有效方法,这是合乎逻辑的并且被 Web 开发人员理解?

我遇到了这段代码:

var inArray = function(a, b, c, d) {
    for (c in b) d |= b[c] === a;
    return !!d
};

它工作正常。有人可以解释一下代码吗?
我还遇到了一个完全相同的问题,可能会使我的问题重复。但我真正的问题在于对上述代码的解释以及为什么在其中使用位运算符。
此外,是否有一种方法无需任何 for 循环或迭代来获取数组中项目的索引?

4

4 回答 4

5
var inArray = function(a, b, c, d) {
    for (c in b) d |= b[c] === a;
    return !!d
};

那是一些糟糕的代码,你应该远离它。位运算符在这里完全没有必要,c而且d作为参数根本没有意义(正如 Raymond Chen 指出的那样,代码的作者可能是为了声明局部变量的安全空间而这样做的——但问题是 iftrue被传入d代码突然被破坏,额外的参数破坏了看一眼声明会提供的任何理解感)。

我将解释代码,但首先,这是一个更好的选择:

function inArray(arr, obj) {
    for (var i = 0; i < arr.length; ++i) {
        if (arr[i] === obj) {
            return true;
        }
    }
    return false;
}

请注意,这取决于数组是实际数组。您可以使用for (k in arr)类型循环将其推广到所有对象。


无论如何,继续解释:

for (c in b) d |= b[c] === a;

这意味着对于 b 中的每个键(存储在 中c),我们将检查是否b[c] === a。换句话说,我们正在对数组进行线性扫描,并对照a.

d |= val是按位或。中的高位val将设置为高d。这在位比在 JS 中更暴露的语言中更容易说明,但它是一个简单的说明:

10011011
01000001
--------
11011011

它只是将每个单独的位与另一个值中的相同位置位进行或运算。

它在这里被滥用的原因是它使代码复杂化并且它依赖于奇怪的隐式强制转换。

x === y返回一个布尔值。在按位表达式中使用布尔值没有什么意义。但是发生的事情是布尔值被转换为非零值(可能1)。

同样,将undefined是什么d。这意味着d它将被转换0为按位的东西。

0 | 0 = 0,但是0 | 1 = 1。所以基本上它是一个美化的:

for (c in b) d = (d || (b[c] === a));

至于!!x那只是用来将某些东西转换为布尔值。 !x将采用 x,将其隐式转换为布尔值,然后将其取反。然后额外的!将再次否定它。因此,它可能会隐式转换为布尔值(!!x为真意味着 x至少是松散的真(1,"string"等),并!!x暗示至少x是松散的假(,等)。0""


这个答案提供了更多选择。请注意,尽管所有这些都是为了回退到本机indexOf,这几乎肯定会比我们在脚本领域中编写的任何代码都要快。

于 2012-12-30T19:18:40.667 回答
2

什么是在数组中查找项目的最有效方法,这是合乎逻辑的并且被 Web 开发人员理解?

本机方法haystack.indexOf(needle) !== -1或尽快返回的循环方法

function inArray(needle, haystack) {
    var i = haystack.length;
    while (i) if (haystack[--i] === needle) return true;
    return false;
};
于 2012-12-30T19:19:12.010 回答
2

这段代码写得很糟糕,几乎不可读。我不认为它是“真棒”...

这是一个重写的版本,希望更具可读性:

function inArray (aElt, aArray) {
  var key;
  var ret = false;
  for (key in aArray)
    ret = ret || (aArray[key] === aElt);
  return ret;
}

for 循环似乎是最自然的方法。您可以递归地执行此操作,但这并不是这里最简单的方法。

于 2012-12-30T19:04:22.663 回答
2

你要求一个递归版本

var inArray = function(arr, needle, index) {
    index = index || 0;
    if (index >= arr.length)
        return false;
    return arr[index] === needle
         ? true
         : inArray(arr, needle, index + 1);
}

console.log(inArray([1,5,9], 9));
于 2012-12-30T20:03:37.660 回答