如何使用数组包含并根据对象的属性检查对象

时间:2019-07-12 10:45:22

标签: javascript arrays filter javascript-objects

我有一个数组classTopics,其中的对象看起来像这样:

{
  questions:2,
  id:49,
  topic:{
    edited: null
    id: 1
    name: "Topic name"
    status: "ACTIVE"
    topicCode:"02"
  }
}

我还有一个数组allTopics,其中对象与上例中的topic属性相同:

 {
    edited: null
    id: 1
    name: "Topic name"
    status: "ACTIVE"
    topicCode:"02"
  }

在选择字段中,我想过滤property topic数组对象中与classTopics相同的所有主题。 所以,像这样:

 <AutoCompleteSelect
   options={allTopics.filter(topic => !classTopics.includes(topic)).map(({name}) => ({value: name, label: name}))}
 />

但是,这不起作用,因为它正在整体检查对象。我该如何做类似的事情来检查对象的属性?

基本上,我想以一种更好的方式实现这一目标:

const filteredTopics = allTopics
                        .filter(topic => 
                          (classTopics.findIndex(classTopic => classTopic.topic.id === topic.id)) === -1);

您可以找到有效的示例here

3 个答案:

答案 0 :(得分:3)

按整个对象(每个属性)比较

您可以使用some检查主题是否在classTopics数组内,并使用everyObject.entries来检查主题数组内的每个属性是否相同:

const classTopics = [{ questions: 2, id: 49, topic: { edited: null, id: 1, name: "Topic name", status: "ACTIVE", topicCode: "02" }}]
const allTopics = [{ edited: null, id: 1, name: "Topic name", status: "ACTIVE", topicCode: "02" }]

const filterTopics = (a, c) => {
  return a.filter(topic => c
    .some(c => Object.entries(c.topic)
      .every(([k,v]) => topic[k] === v)
    )
  )
}

console.log(filterTopics(allTopics, classTopics))

按ID比较

正如评论中所建议的那样,检查整个对象是过大的,ID的目的是唯一地识别对象-使用ID可以使效率更高:

const classTopics = [{ questions: 2, id: 49, topic: { edited: null, id: 1, name: "Topic name", status: "ACTIVE", topicCode: "02" }}]
const allTopics = [{ edited: null, id: 1, name: "Topic name", status: "ACTIVE", topicCode: "02" }]

const filterTopics = (a, c) => a.filter(topic => c.some(t => t.topic.id === topic.id))

console.log(filterTopics(allTopics, classTopics))

答案 1 :(得分:1)

为简单起见,我更喜欢在js文件而不是html中进行此过滤。 我也在这里使用lodash js lib来减少代码大小。

const classTopics = [{ questions: 2, id: 49, topic: { edited: null, id: 1, name: "Topic name", status: "ACTIVE", topicCode: "02" }}]
const allTopics = [{ edited: null, id: 1, name: "Topic name", status: "ACTIVE", topicCode: "02" }]

const topicsToshow = _.unionWith(allTopics,classTopics,(cT,aT)=> aT.id===cT.topic.id)
console.log(topicsToshow)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.min.js"></script>

答案 2 :(得分:1)

您可以仅按主题ID,名称或其他属性进行比较,而不要按整个主题对象进行比较:

allTopics
  .filter(topic => !classTopics.map(t => t.id).includes(topic.id))
  .map(topic => ({value: topic.name, label: topic.name}))