首页 > 解决方案 > 筛选项列表如何依赖于另一个列表

问题描述

我有一组脚本“列表”和一组选定的用户“用户”,每个用户可以有几个这样的脚本。

如何过滤“列表”脚本数组以仅将那些脚本用于正确的语句:

例子

let list = [{name: 'script1', id:'1'}, {name: 'script2',id:'2'},{name: 'script3',id:'3'}]

let users = [
{name: 'user1', scripts:[{name: 'script1',id:'1'}]},
{name: 'user2', scripts:[{name: 'script1',id:'1'},{name: 'script2',id:'2'}]}
]

let result = list.filter(...)  //=> let list = [{name: 'script2'},{name: 'script3'}]

我的尝试看起来很糟糕

let result = list.filter(item => {
      return  users.filter(user => {
        return user.scripts.some(el => {
          return el.id !== item.id
        })
      })
    })

标签: javascript

解决方案


  1. 使用数组Array#reduceusers创建一个作为脚本和作为Map拥有它的数量keyidvalueusers
  2. Array#filterlist数组上使用,获取scripts所有未使用users的对象,然后,如果您只想返回name使用的对象Array#map

const list = [
  { name: 'script1', id:'1' }, 
  { name: 'script2', id:'2' },
  { name: 'script3', id:'3' }
];
const users = [
  { name: 'user1', scripts:[ { name: 'script1', id:'1' } ] },
  { name: 'user2', scripts:[ { name: 'script1', id:'1' }, { name: 'script2', id:'2' } ] }
];
const TOTAL = users.length;

const usage = users.reduce((scriptUsagesMap, { scripts=[] }) => {
  scripts.forEach(({ id }) => {
    const count = scriptUsagesMap.get(id) || 0;
    scriptUsagesMap.set(id, count + 1);
  });
  return scriptUsagesMap;
}, new Map);

const result = list
  .filter(({ id }) => usage.get(id) !== TOTAL)
  .map(({ name }) => ({ name }));

console.log(result);


推荐阅读