I have an array classTopics
where an object looks like this:
{
questions:2,
id:49,
topic:{
edited: null
id: 1
name: "Topic name"
status: "ACTIVE"
topicCode:"02"
}
}
And I also have an array allTopics
where the objects are the same as topic property in the example above:
{
edited: null
id: 1
name: "Topic name"
status: "ACTIVE"
topicCode:"02"
}
In the select field I would like to filter all the topics that are the same as a property topic
in the objects of the classTopics
array. So, something like this:
<AutoCompleteSelect
options={allTopics.filter(topic => !classTopics.includes(topic)).map(({name}) => ({value: name, label: name}))}
/>
But, that is not working since it is checking the objects as a whole. How can I do something similar where I could check it against the property on the object?
Basically what I am trying to achieve is this in a nicer way:
const filteredTopics = allTopics
.filter(topic =>
(classTopics.findIndex(classTopic => classTopic.topic.id === topic.id)) === -1);
You can find the working example here .
You can use some
to check if the topic is inside the classTopics array, and use every
with Object.entries
to check that each property is the same inside the topics array:
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))
As suggested in the comments, checking the entire object is overkill, the purpose of an ID is to identify an object uniquely - using ID's makes for a much more efficient solution:
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))
I will prefer to do this filtering in js file instead of html for simplicity. Also I am using here lodash js lib to reduce code size.
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>
You can compare just by topic ID, name or other property instead of whole topic objects:
allTopics
.filter(topic => !classTopics.map(t => t.id).includes(topic.id))
.map(topic => ({value: topic.name, label: topic.name}))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.