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ですか?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)is 1 なので、false を返します
  • 5: array.IndexOf(10) == 4? // noarray.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メソッドが項目: 103010、 thenを通過するとき、その上で100を実行indexOfします。

の場合10indexOfが返され0ます。そしてidxまた0です。

の場合30indexOfが返され1ます。そしてidxまた1です。

の場合10indexOfが返され0ます。しかし、idxなります2

の場合100indexOfが返され3ます。そしてidxまた3です。

そのため、[10, 30, 100]元の単なるクローンではなく、返されます。

于 2012-12-19T05:31:09.723 に答える
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では 2 番目の列がチェックされます。同じ番号でない場合は重複しています。アイテムが一意 ( *) であるためには、インデックスとインデックスの位置が一致する必要があります。

于 2012-12-19T05:35:16.193 に答える
0

この関数 (名前のとおり) は、元の配列内の一意の項目を取得し、それらを新しい配列で返します。したがって、元の配列に個別のアイテムがある場合、クローンが返されます。

指定されたアイテムの最初のindexOfインデックスを返すことを忘れないでください。そのため、現在の項目が配列に 2 回表示される場合、フィルター値は 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 に答える