问题
I am trying to filter by child elements in lodash. I use firebase, which generates random keys for objects. The data structure here is like:
contact: {
name: My Name,
events: {
-fdhu9euwf9hud: {
eventName: day 1
courseId: -3jfe2j09ej
}
-efdshkfhhiufd: {
eventName: day 2
courseId: -3jfe2j09ej
}
-fh9238fh9duf2: {
eventName: day 1
courseId: -dvh89wdfhoiw
}
}
}
I am trying to find all people (and events) that belong to a certain course which will be passed in as searchCourseID. I just don't know what to use for MYSTERYKEY below or if there is another way I should be handling this situation.
contactsWithCourse = (
_(this.props.contacts)
.filter(({events}) => {
if (events && events[MYSTERYKEY].courseId == searchCourseID) {
return true
} else {
return false
}
}
)
回答1:
You can filter the results using by iterating the events using _.some(), and check if at least one of them contains the requested searchCourseID. Note that collection methods, such as _.some() and _.filter() can work on arrays and objects (collections), and "ignore" the (mystery) keys of the items in the objects:
const result = _.filter(contacts, ({
events
}) => _.some(events, ({
courseId
}) => courseId === searchCourseID));
const searchCourseID = '-dvh89wdfhoiw';
const contacts = {
'-uf39uhef2': {
name: 'My Name',
events: {
'-fdhu9euwf9hud': {
eventName: 'day 1',
courseId: '-3jfe2j09ej'
},
'-efdshkfhhiufd': {
eventName: 'day 2',
courseId: '-3jfe2j09ej'
},
'-fh9238fh9duf2': {
eventName: 'day 1',
courseId: '-dvh89wdfhoiw'
}
}
},
'-willBeFiltered': {
name: 'filtered out',
events: {
'-fdhu9euwf9hud': {
eventName: 'day 1',
courseId: '-3jfe123123'
},
'-efdshkfhhiufd': {
eventName: 'day 2',
courseId: '-3jfedf3433'
},
'-fh9238fh9duf2': {
eventName: 'day 1',
courseId: '-dvh8111111'
}
}
}
};
const result = _.filter(contacts, ({
events
}) => _.some(events, ({
courseId
}) => courseId === searchCourseID));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
The same logic works without lodash, using ES6 Object.values():
const result = Object.values(contacts).filter(({
events
}) => Object.values(events).some(({
courseId
}) => courseId === searchCourseID));
const searchCourseID = '-dvh89wdfhoiw';
const contacts = {
'-uf39uhef2': {
name: 'My Name',
events: {
'-fdhu9euwf9hud': {
eventName: 'day 1',
courseId: '-3jfe2j09ej'
},
'-efdshkfhhiufd': {
eventName: 'day 2',
courseId: '-3jfe2j09ej'
},
'-fh9238fh9duf2': {
eventName: 'day 1',
courseId: '-dvh89wdfhoiw'
}
}
},
'-willBeFiltered': {
name: 'filtered out',
events: {
'-fdhu9euwf9hud': {
eventName: 'day 1',
courseId: '-3jfe123123'
},
'-efdshkfhhiufd': {
eventName: 'day 2',
courseId: '-3jfedf3433'
},
'-fh9238fh9duf2': {
eventName: 'day 1',
courseId: '-dvh8111111'
}
}
}
};
const result = Object.values(contacts).filter(({
events
}) => Object.values(events).some(({
courseId
}) => courseId === searchCourseID));
console.log(result);
回答2:
to avoid unknown keys use _.values
_.filter(contacts, (user) => {
return _.chain(user)
.get('events')
.values()
.map('courseId')
.includes(searchCourseID)
.value();
});
来源:https://stackoverflow.com/questions/40824649/how-to-filter-in-lodash-when-there-is-an-unknown-key