4

我正在努力提高我对 Javascript 的理解,所以我一直在浏览 Zepto 库。我遇到了这条线:

uniq = function(array){
    return array.filter(function(item, idx){
        return array.indexOf(item) == idx
    })
}

这个函数的目的是什么?据我所知,它正在创建一个新的、独特的元素数组,对吧?但它本质上不只是克隆数组吗?如果是这样,不是array.slice()更快吗?

array.indexOf(item)最后,更改为不会提高性能array.indexOf(item,idx)吗?或者更好,只是return true?什么时候array.indexOf(item)==idx 等于真?这是为了防止重复项目吗?但那什么时候会真正发生呢?

4

5 回答 5

3

it is creating a new, unique array of elements, right?

它只是过滤您的数组元素以返回唯一元素。

演示

But isn't it essentially just cloning the array?

不,正如我上面解释的那样。

If so, wouldn't array.slice() be faster?

切片不会删除重复项。

Finally, wouldn't it increase performance to change array.indexOf(item) to array.indexOf(item,idx)? Or better yet, just return true?

如果您只返回 true,您将无法确定元素是否重复。

演示

When does array.indexOf(item)==idx not equal true?

示例:
我有以下数组:

['10', '20', '30', '20', '10']

迭代

  • 1 array.IndexOf(10) == 0:?// 是的,所以返回 true
  • 2 array.IndexOf(20) == 1:?// 是的,所以返回 true
  • 3 array.IndexOf(30) == 2:?// 是的,所以返回 true
  • 4 array.IndexOf(20) == 3:?// 否,因为array.indexOf(20)是 1,所以返回 false
  • 5 array.IndexOf(10) == 4:?// 否,因为array.indexOf(10)是 2,所以返回 false

因此,当元素已经被发现时,它会变为 false,因为索引不同。

于 2012-12-19T05:31:47.473 回答
1

似乎此代码正在消除重复项。

于 2012-12-19T05:29:13.947 回答
1

啊,我看到了我们正在质疑的“差异”。不过,在您的编辑中,您有点回答了。我认为此方法返回一个新数组,其中包含原始数组中的唯一值。

当该indexOf方法扫描数组时,它会找到当前检查项目的第一次出现。如果出现的索引与正在检查的当前索引不同,则indexOf结果将不等于idx。因此,它不会返回该值,因为它要么未找到,要么在数组中较早找到(这意味着它是重复的)。

这是一个例子:

[10, 30, 10, 100]

filter方法通过项目: 10, 30, 10, then100时,它将对其执行indexOf

10indexOf必归0。而且idx也是0

30indexOf必归1。而且idx也是1

10indexOf必归0。但是idx2

100indexOf必归3。而且idx也是3

因此,[10, 30, 100]将被退回,而不仅仅是原始的简单克隆。

于 2012-12-19T05:31:09.723 回答
0

该函数(如命名)采用原始数组中的唯一项,并在新数组中返回它们。所以如果原始数组有不同的项目,它只会返回一个克隆。

请记住,indexOf返回给定项目的第一个索引。因此,如果当前项在数组中出现两次,则过滤器值将为 false。

例如。

var a = [1, 2, 3];
var b = [1, 2, 3, 2];

console.log(uniq(a));  // [1,2,3]
console.log(uniq(b));  // [1,2,3]

​</p>

于 2012-12-19T05:29:58.087 回答
0

正如其他人已经说过的那样,这消除了数组中的重复项。刚刚添加了我的答案以说明为什么会这样。如果您注销过滤器函数中的值,您将看到以下模式:

array.filter(function( item, idx ){
  console.log( item, idx, array.indexOf( item ) );
  ...
  ...

console.log( uniq( ['a','a','b','b','c','c','c','d'] ) );
/*
a 0 0 *
a 1 0
b 2 2 *
b 3 2
c 4 4 *
c 5 4
c 6 4
d 7 7 *
*/

检查最后一列,这就是确定项目是否已经存在的原因,因此比较array.indexOf(item) == idx检查第二列,如果它不是相同的数字,则它是重复的。要使项目唯一 ( *),索引和索引位置必须匹配。

于 2012-12-19T05:35:16.193 回答