非常困惑这种行为(返回数组的唯一元素的简单函数)

时间:2015-06-02 05:21:38

标签: javascript arrays

这是我的代码:

uniq = function(array) {
    var result = [];
    for (var i = 0; i < array.length; i++) {
        console.log(array[i], " is in ", result, (array[i] in result));
        if (!(array[i] in result)) {
            result.push(array[i]);
        } else {}
    }
    return result;
};

uniq([1, 2, 3, 3, 4, 4]);

输出是:

1'在'[] false

2'在'[1] false

3'在'[1,2] false

3'在'[1,2,3] false&lt; --- HUH?

4'在'[1,2,3,3]假

4'在'[1,2,3,3,4]中是真的&lt; ---现在它可以正常工作

有人可以告诉我吗?为什么(!(array [i] in result))第一次没有评估为true,而是第二次?

3 个答案:

答案 0 :(得分:4)

p in o表示&#34;对象o具有名为p的属性&#34; (或者在数组的情况下,等效地#34;数组o是否有索引p&#34;),而不是#34;数组o是否有价值 p&#34;。 [1, 2, 3]的索引为012 - 无3[1, 2, 3, 3, 4]的索引从04,因此4是&#34;在&#34;。

使用result.indexOf(array[i]) !== -1作为成员资格测试(但请注意它doesn't work in IE<9(点击&#34;显示过时的浏览器&#34;),您需要通过循环手动执行,或使用通过循环来完成它的垫片 - 即slooooow)

评论中提到的另一种方法是哈希表方法,但是有点受限制。

var uniq = function(array) {
  var result = [];
  var hash = {};
  for (var i = 0; i < array.length; i++) {
    if (!hash[array[i]]) {
      result.push(array[i]);
      hash[array[i]] = true;
    }
  }
  return result;
}

这不依赖于任何新功能,应该可以在任何地方使用,而且速度相当快 - 它只需要花费更多的内存。

答案 1 :(得分:1)

要回答你的问题,

  

为什么(!(array [i] in result))第一次没有评估为true   但这是第二次吗?

in关键字检查是否value of array[i] is a key in result or not。如果结果

中存在键数组[i],它将返回true

在您的示例中,

1'在'[]中,因为结果数组没有键

2'在'[1]中为false,因为0是结果数组中唯一的键

3'在'[1,2]中为false,因为0和1是结果数组中唯一的键

3'在'[1,2,3]中为false,因为0,1和2是结果数组中的键

4'在'[1,2,3,3]中为false,因为0,1,2和3是结果数组中的键

4'在'[1,2,3,3,4]中为真,因为0,1,2,3和4是结果数组中的键

要获得所需结果,请使用indexOf功能,如下面的代码

uniq = function(array) {
    var result = [];
    for (var i = 0; i < array.length; i++) {
        console.log(array[i], " is in ", result, (result.indexOf(array[i]) !== -1));
        if (!(array[i] in result)) {
            result.push(array[i]);
        } else {}
    }
    return result;
};

答案 2 :(得分:0)

使用indexOf检查数组中是否存在元素:

  

indexOf()方法返回可在数组中找到给定元素的第一个索引,如果不存在则返回-1。

uniq = function(array) {
    var result = [];
    for (var i = 0; i < array.length; i++) {
        if (result.indexOf(array[i]) === -1) {
            result.push(array[i]);
        }
    }
    return result;
};

console.log(uniq([1, 2, 3, 3, 4, 4]));

演示:https://jsfiddle.net/tusharj/uvzwqw9s/

文档:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf