Javascript - 检查数组中值的出现次数并返回 true 或 false

Javascript - Check array for number of occurences of value and return true or false

提问人:Rafael Polonio 提问时间:11/11/2022 最后编辑:Rafael Polonio 更新时间:11/11/2022 访问量:83

问:

我有一个具有属性状态的对象数组,我想在其中返回 false IF

我有(零个具有“返回”或零“已订购”状态的插槽或 1 个具有“验证”或 1 个“活动”状态的插槽)

const slots = [
  {
    status: 'void'
  },
  {
    status: 'closed'
  },
  {
    status: 'ordered'
  },
  {
    status: 'verification'
  },
  {
    status: 'active'
  }
]

我不想做喜欢

x = slots.filter((val) => val.status === 'verification' || val.status === 'active'
 if (x.length > 1) return false

y = slots.filter((val) => val.status === 'return' && val.status === 'ordered')
 if (y.length > 0) return false

有没有办法在一个“功能”中更有效地做到这一点?

JavaScript 数组 过滤器

评论

0赞 Konrad 11/11/2022
我不想喜欢 - 为什么?只需一个电话 - 你说的电话是什么意思?
0赞 bloodyKnuckles 11/11/2022
需要明确的是,您正在寻找 IF:(带有“return”的零插槽)或(带有“ordered”的零插槽)或(1 个带有“verification”的插槽)或(1 个带有“active”的插槽)??false
0赞 EssXTee 11/11/2022
如果您尝试使用单个 来执行此操作,我看不到这种情况发生,因为您的条件需要不同的长度,并且无法同时验证 0 长度和 1 长度。不过,if/return 语句可以压缩为 1 行。filter()filter()
0赞 Rafael Polonio 11/11/2022
@bloodyKnuckles是的..对不起,我添加了不必要的(
0赞 bloodyKnuckles 11/11/2022
或者,如果: (1 个或多个带有“return”的插槽)AND (1 个或多个带有“ordered”的插槽)AND ((0 或 (2 或更多)) 带有“verification”的插槽) AND (0 或 (2 或更多)) 带有“active”的插槽)??true

答:

0赞 Ryan Wilson 11/11/2022 #1

如注释中所述,由于条件不同,使用时您仍然需要多次调用该方法,但您可以将其组合成一行,如下所示,条件和(左侧计算为 false)短路,在某些情况下只能产生一次调用:filterfilterfilter

const slots = [
  {
    status: 'void'
  },
  {
    status: 'closed'
  },
  {
    status: 'ordered'
  },
  {
    status: 'verification'
  },
  {
    status: 'active'
  }
];

function checkslots(slots){
    return slots.filter((val) => val.status === 'verification' || 
        val.status === 'active').length <= 1 &&
        slots.filter((val) => val.status === 'return' && 
        val.status === 'ordered').length <= 0;
}

console.log(checkslots(slots));

0赞 James 11/11/2022 #2

我倾向于用插槽制作一个对象并测试创建的属性。我认为这样的逻辑更清晰一些,因为条件非常复杂。

const slots = [{
    status: 'void'
  },
  {
    status: 'closed'
  },
  {
    status: 'ordered'
  },
  {
    status: 'verification'
  },
  {
    status: 'active'
  }
]

function check(slots) {
  const o = Object.fromEntries(slots.map(s => [s.status, true]))

  if ((o.verification || o.active) && !o.return && !o.ordered) return false;

  return true;
}

console.log(check(slots));

评论

0赞 merryweather 11/11/2022
不过,我认为这并不能反映 AND 检查。> 0> 1
0赞 James 11/11/2022
它应该,@caTS,但不幸的是,我不能把它变成一个片段,因为它不喜欢我的手机。
0赞 James 11/11/2022
谢谢!现在问题的逻辑已经改变,所以让我们看看这在哪里解决。
0赞 Andrew Parks 11/11/2022 #3

此方法计算每个不同状态的计数,然后将 OR 规则应用于这些计数。

const slots = [{status:"void"},{status:"closed"},{status:"ordered"},{status:"verification"},{status:"active"}];
const c = slots.reduce((a,{status:s})=>(a[s]??=0, a[s]++, a),{});
const r = !( !c.return || !c.ordered || c.verification===1 || c.active===1 );
console.log(r);

0赞 PeterKA 11/11/2022 #4

For 可以使用 with 和 for 的组合 和 和 方法的组合,如下所示:xArray#filterArray#includesyArray#everyArray#includes

const 
   slots = [ { status: 'void' }, { status: 'closed' }, { status: 'ordered' }, { status: 'verification' }, { status: 'active' } ],
   
   x = slots
     .filter(
         ({status}) => !['verification','active'].includes(status)
     ).length === 1,
   
   y = slots
     .every(
         ({status}) => !['return', 'ordered'].includes(status)
     );
     
console.log( x, y, x || y );