获取结果长度Array.prototype.some()

时间:2019-04-03 18:36:29

标签: javascript arrays

我有一个条件,可以通过Array.prototype.some()进行检查。考虑这个数组:

const coolArray = [
  { isCool: false },
  { isCool: false },
  { isCool: true }
]

const isCool = coolArray.some(item => item.isCool === true)

if (isCool) {
  console.log("hello I'm cool!")
}

但是,我希望在item.isCooltrue 并且数组中至少有两项符合条件时进行检查。因此,上面的示例将不会输出该消息,因为只有一个true条件。

MDN上,此方法的引用为arr.some(callback(element[, index[, array]])[, thisArg])。但是[, array]引用原始数组而不是其克隆,因此执行以下操作将输出相同的结果:

const isCool = coolArray.some((item, index, arr) => {
  return item.isCool === true && arr.length > 1
})

我知道我可以避免.some()并使用mapfor遍历数组并将结果保存在外部数组中,这样我就可以检查长度了,类似于:

const isCoolArr = []
coolArray.map(item => item.isCool ? isCoolArr.push(item) : false)
console.log('expected result:', isCoolArr.length) // outputs 1

但是我对使用这种方法并寻找更简单的替代方法并不特别满意。 .some()是否可以满足我的需要,或者我需要其他替代方法?除了我上面提到的情况以外,还有其他吗?

5 个答案:

答案 0 :(得分:2)

使用.filter(),您将失去使用.some()所获得的短路优势。一种选择是使用回调外部的变量。

const coolArray = [{isCool: false},{isCool: false},{isCool: true}]
let count = 0

const isCool = coolArray.some(item => (count += item.isCool) >= 2)

if (isCool) {
  console.log("hello I'm cool!")
} else {
  console.log("not cool enough")
}

这利用了将布尔值转换为数字的优势。如果您不喜欢,可以更加明确。

const coolArray = [{isCool: false},{isCool: false},{isCool: true}]
let count = 0

const isCool = coolArray.some(item => item.isCool && ++count >= 2)

if (isCool) {
  console.log("hello I'm cool!")
} else {
  console.log("not cool enough")
}

或者在不添加额外变量的情况下实现!

const coolArray = [{isCool: false},{isCool: false},{isCool: true}]
let isCool = 0;

isCool = coolArray.some(item => item.isCool && ++isCool >= 2);

if (isCool) {
  console.log("hello I'm cool!")
} else {
  console.log("not cool enough")
}

答案 1 :(得分:2)

Array.reduce

const coolArray = [
  { isCool: false },
  { isCool: false },
  { isCool: true }
]

const count = coolArray.reduce((accum, item) => Number(item.isCool) + accum, 0)

if (count >= 2) {
  console.log("Hello I'm cool!")
}

答案 2 :(得分:1)

您可以使用filter并检查长度

const coolArray = [
  { isCool: false },
  { isCool: false },
  { isCool: true }
]

const isCool = coolArray.filter(item => item.isCool === true)

if (isCool.length > 1 ) {
  console.log("hello I'm cool!")
} else{
  console.log('length is less than 2')
}

答案 3 :(得分:1)

其他人建议使用filter并检查length。我想在atLeast创建一个方法,如果满足条件,该方法将会中断

const coolArray = [
  { isCool: false },
  { isCool: false },
  { isCool: true }
]

function x(cb,num){
  let count = 0;
  for(let i =0;i<this.length;i++){
    if(cb(this[i],i,this)) count++;
    if(count === num) return true;
  }
  return false;
}

Object.defineProperty(Array.prototype,'atLeast',{
  value:x,
  writeable:true
})

console.log(coolArray.atLeast(x => x.isCool === true,1)); //true
console.log(coolArray.atLeast(x => x.isCool === true,2)); //false

答案 4 :(得分:1)

这是一个简单的通用实现,一旦达到限制就会停止:

let someTimes = (array, fn, count) => array.some(x => !(count -= Boolean(fn(x))));

console.log(someTimes(
    [1,2,3,44,5,66,7,99],
    x => x > 10,
    2
))

或者甚至更好,

let countDown = (fn, count) => x => !(count -= !!fn(x));


console.log(
    [1, 2, 3, 44, 5, 66, 7, 99].some(countDown(x => x > 10, 2))
)

在大多数情况下,提早退出优化并不值得,您可以简单地使用更有用的通用计数器函数:

let countWhere = (array, fn) => array.reduce((n, x) => n + Boolean(fn(x)), 0);

console.log(countWhere(
    [1,2,3,44,5,66,7,99],
    x => x > 10
) >= 2)