【问题标题】:How to use indexOf with filter() in JavaScript如何在 JavaScript 中使用 indexOf 和 filter()
【发布时间】:2017-08-05 13:46:45
【问题描述】:

这是我找到的作为该问题答案的代码:Write a JavaScript program to remove duplicate items from an array (ignore casesensitive)。

var arr1=[3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3, 'A'];

var uniqueArray = arr1.filter(function(elem,i,rep){
    return i == rep.indexOf(elem);
})
console.log(uniqueArray);

我知道 filter() 是做什么的,并且 indexOf 用于查找元素第一次出现的索引,但是我不明白这一行是怎么回事:

i == rep.indexOf(elem);

仅将唯一元素引入 uniqueArray。

【问题讨论】:

  • var uniqueArray = [...new Set(arr1)];

标签: javascript arrays indexof


【解决方案1】:

var arr1 = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3, 'A'];

var uniqueArray = arr1.filter(function(elem,i,rep){
        return i == rep.indexOf(elem);
    });
    
console.log(uniqueArray);

这里 elem 将包含数组的每个元素,i 将是当前 elem 的索引,rep 将包含整个数组
现在 rep.indexOf(elem); 总是会给出元素第一次出现的索引现在 Array.prototype.filter() 的工作方式是,如果你返回 true,它不会过滤它但是如果你返回 false,它会过滤掉它,所以除了第一次出现之外的每个元素都会被过滤掉

【讨论】:

    【解决方案2】:

    根据MDN关于Array#indexOf的文章:

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

    在您提供的代码中:

    var uniqueArray = arr1.filter(function(elem,i,rep){
        return i == rep.indexOf(elem);
    })
    

    过滤器回调中的变量i是数组中当前项的索引。如果一个项目出现不止一次,则当前索引 (i) 和 Array#indexOf 返回的索引对于第一次之后的重复值会有所不同。这种情况下过滤回调会返回false,重复的值会被过滤掉。

    【讨论】:

      【解决方案3】:
      i == rep.indexOf(elem);
      

      将始终返回在数组中找到该元素的第一个索引,因此在过滤后的数组中只会接受任何副本中的第一个。

      【讨论】:

      • 我喜欢你解释这种行为的方式。您在简洁的同时给出了完整的解释。
      【解决方案4】:

      来自w3schools

      array.filter(function(currentValue, index, arr), thisValue)

      在您示例中的 .filter 方法中,该函数正在遍历每个索引并使用 indexOf 来查找您所说的:“第一次出现的索引。”

      在迭代过程中,索引i 遇到重复元素,您使用测试来查看此i 是否等于给定数组中当前元素的索引。

      来自w3schools

      filter() 方法创建一个数组,其中填充了所有通过测试的数组元素(作为函数提供)。

      您示例中的测试是i == rep.indexOf(elem);

      当迭代到达索引2时,元素为a。但是,元素a 的第一次出现在索引1 处。此时,i=2rep.indexOf(elem) = 1。测试返回false,因为2==1false

      false 返回从新创建的数组中排除索引2 处的重复元素a

      【讨论】:

        【解决方案5】:

        var arr1 = [3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3, 'A'];
        
        var newArray = 
         arr1.filter(
          (obj,index,array)=> {return array.map(el => el).indexOf(obj) == index}
                    );
          
        console.log(newArray);

        【讨论】:

          【解决方案6】:

          return 是测试 i 是否等于找到的元素的索引,因此函数 return 将是 true 或 false。

          【讨论】:

            【解决方案7】:

            var arr1=[3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3, 'A'];
            
            var uniqueArray = arr1.filter(function(elem,i,rep){
                return i == rep.indexOf(elem);
            })
            console.log(uniqueArray);

            让我试着解释一下代码及其结果。

            Array.prototype.filter 可以接受三个参数。在您的代码中,

            1. elemArray arr1 的一个元素。
            2. ielemarr1 中的索引。
            3. 它在arr1 中有一个索引。
            4. repArrayarr1 相同。只需将rep 视为arr1

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

            现在我们可以试着理解代码的作用了。

            1. 如果我们假设elem 的值为'a'rep.indexOf(elem); 将返回1
            2. 假设elem'a'elemi的索引为3return i == rep.indexOf(elem);将返回false,当i时返回true 1.

            这意味着过滤器将返回一个数组,其中包含 Array 中每个 元素第一个索引 中的值。

            让我们模拟一下代码:

            var arr1=[3, 'a', 'a', 'a', 2, 3, 'a', 3, 'a', 2, 4, 9, 3, 'A'];
            
            var uniqueArray = arr1.filter(function(elem,i,rep){
                console.log("index  :"+i+" first indext of this value: "+rep.indexOf(elem)+" element :"+elem+ " is filterable :"+(i == rep.indexOf(elem)) );
                return i == rep.indexOf(elem);
            })
            console.log(uniqueArray);

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-06-08
              • 1970-01-01
              • 2016-06-07
              • 1970-01-01
              • 1970-01-01
              • 2015-02-11
              • 1970-01-01
              相关资源
              最近更新 更多