首页 > 解决方案 > 复杂的 .reduce 过滤数组

问题描述

所以我正在尝试编写一个花哨的reduce函数(我可以循环,但是......)。希望对此有所帮助-

初始items数组:

const items = [
  {'labels': ['a'], 'team': "infra"}, 
  {'labels': [], 'team': "infra"},
  {'labels': [], 'team': "InfraNew"},
  {'labels': ['new'], 'team': "infrastructure org"}, 
  {'labels': ['aaa'],'team': "infra"},
  {'labels': [], 'team': "Infra 1"},
  {'labels': ['b'],'team': "infra"},
  {'labels': ['a'],'team': "DT"},
  {'labels': ['c'], 'team': "DT"},
  {'labels': ['c', 'b'], 'team': null}
]

filters对象。

const filters = {
  team: ['infra', 'DT'],
  labels: ['a', 'b']
}

目标是results在过滤后的团队中获取带有标签的项目数组。(因此,如果团队没有匹配的标签,则应将其排除)。

const results = [
  {'labels': ['a'],'team': "infra"},
  {'labels': ['b'],'team': "infra"},
  {'labels': ['a'],'team': "DT"},
]

这就是我所拥有的,但似乎无法正确调节。

function filtering(res, el) {
  for (let i = 0; i < Object.keys(filters).length; i++) {
    const key = Object.keys(filters)[i];
    let filterArray = filters[key];
    const elementValue = el[key];
    if (!elementValue) return res;
    if (key === 'labels') {
      if (elementValue.length === 0) return res;
      elementValue.map(elementValueItem => {
        if (filterArray.indexOf(elementValueItem) < 0) {
            return res
        }
      })
    } else if (filterArray.indexOf(elementValue) < 0) {
      return res;
    }
  }
  res.push(el);
  return res;
}

var results = items.reduce(filtering, [])
console.log(results)

这是jsfiddle

标签: reduce

解决方案


如果您从Array.prototype.filter. 我在下面为你做了

const items = [
  {'labels': ['a'], 'team': "infra"}, 
  {'labels': [], 'team': "infra"},
  {'labels': [], 'team': "InfraNew"},
  {'labels': ['new'], 'team': "infrastructure org"}, 
  {'labels': ['aaa'],'team': "infra"},
  {'labels': [], 'team': "Infra 1"},
  {'labels': ['b'],'team': "infra"},
  {'labels': ['a'],'team': "DT"},
  {'labels': ['c'], 'team': "DT"},
  {'labels': ['c', 'b'], 'team': null},
]

const filters = {
  team: ['infra', 'DT'],
  labels: ['a', 'b'],
}

const shouldKeep = item => {
  if (!filters.team.includes(item.team)) {
return false
  }
  if (item.labels.length === 0) {
return false
  }
  for (const label of item.labels) {
if (!filters.labels.includes(label)) {
  return false
}
  }
  return true
}

console.log(
  items.filter(shouldKeep)
)


推荐阅读