【问题标题】:Javascript: How to check if array of object has one and only one item with given value?Javascript:如何检查对象数组是否有一个且只有一个具有给定值的项目?
【发布时间】:2017-12-16 13:43:36
【问题描述】:

我知道在 Javascript 中,我可以在数组上使用 .some.every 来检查它们是否至少有一个项目或每个项目都通过了提供的函数实现的测试。

这里有一些例子:

[2, 5, 8, 1, 4].some(x => x > 10);  // false
[12, 5, 8, 1, 4].some(x => x > 10); // true

[12, 5, 8, 130, 44].every(x => x >= 10); // false
[12, 54, 18, 130, 44].every(x => x >= 10); // true

我正在寻找检查一个数组是否有“一个且只有一个”项通过给定函数。 我想要一些类似以下的方法:

[12, 5, 12, 13, 4].oneAndOnlyOne(x => x >= 10); // false
[2, 11, 6, 1, 4].oneAndOnlyOne(x => x >= 10); // true

您是否知道任何新的 ECMA 脚本 6 方式或任何简单/快速的方式,即使使用 lodash,也可以检查数组中是否只有一个且唯一出现的具有特定值的项目?

【问题讨论】:

  • [...].filter(x => x > 10).length === 1

标签: javascript arrays ecmascript-6 lodash


【解决方案1】:

您可以使用Array#filter 达到所需的结果。

const oneAndOnlyOne = arr => arr.filter(v => v >= 10).length == 1;

console.log(oneAndOnlyOne([12, 5, 12, 13, 4]));
console.log(oneAndOnlyOne([2, 11, 6, 1, 4]));

【讨论】:

  • 这会将函数应用于数组中的每个元素,理论上这可能是一个问题,因为元素很多,或者函数很昂贵。
【解决方案2】:

可能最有效的解决方案是简单循环:

function findOne(arr) {
  var foundOne = false;
  for(var i = 0; i < arr.length; ++i) {
    if(arr[i] > 10)
      if(foundOne) return false;
      else foundOne = true;
  }
  return foundOne;
}

已经有一些工具可以做到这一点。比如ramda。你可以找到一个适合你的。

【讨论】:

    【解决方案3】:

    在找到第一个匹配的点处对数组进行切片,然后在数组的剩余部分中搜索,如

    function oneAndOnlyOne(arr, fn) {
      const pos = arr.findIndex(fn);
      return pos >= 0 && !arr.slice(pos + 1).find(fn);
    }
    
    const tests = [[12, 5, 12, 13, 4], [2, 11, 6, 1, 4], [1, 2, 3]];
      
    for (const test of tests) 
      console.log(String(test), oneAndOnlyOne(test, x => x >= 10));

    【讨论】:

      【解决方案4】:

      尝试filter,数组长度匹配1。并使用Array.prototype.oneAndOnlyOne添加的回调方法

      Array.prototype.oneAndOnlyOne=function(callback){
        return this.filter(callback).length == 1
      }
      
      console.log([12, 11, 6, 1, 4].oneAndOnlyOne(x=> x >= 10)) // false
      console.log([2, 11, 6, 1, 4].oneAndOnlyOne(x=> x >= 10)) // true

      【讨论】:

        【解决方案5】:

        你可以给你的数组添加一个函数(毕竟它是一个对象):

        var arr = [30];
        arr.oneAndOnlyOne = function(numToCheck) { 
            return this.filter(function(x) {
                return x >= numToCheck
            }).length === 1
        }
        
        arr.oneAndOnlyOne(30); //true
        arr.push(30);
        arr.oneAndOnlyOne(30); //false
        

        【讨论】:

          猜你喜欢
          • 2018-07-01
          • 2019-11-15
          • 1970-01-01
          • 1970-01-01
          • 2018-04-18
          • 2023-02-09
          • 2012-06-05
          • 1970-01-01
          • 2021-01-30
          相关资源
          最近更新 更多