I have a filter method that looks like this
Object.values(state.storeLayout.items).flatMap((level) =>
level.poi?.filter((x) =>
(x.guid === guid)) ?? []).map((poi) => poi.coordinate)
However I also want to do:
Object.values(state.storeLayout.items).flatMap((level) =>
level.portals?.filter((x) =>
(x.guid === guid)) ?? []).map((poi) => poi.coordinate)
My question how is how I can concat the two filter methods
level.portals?.filter((x) =>
(x.guid === guid)) ?? [])
level.poi?.filter((x) =>
(x.guid === guid)) ?? [])
inside flatMap, so that I only have one function
so basically something like this
Object.values(state.storeLayout.items).flatMap((level) =>
level.poi?.filter((x) =>
(x.guid === guid)
&&
level.portal?.filter((x) =>
(x.guid === guid)
) ?? []).map((poi) => poi.coordinate)
CodePudding user response:
Maybe something like this?
Object.values(state.storeLayout.items).flatMap((level) => {
let tmpLevel = {...level}
tmpLevel.portal = tmpLevel.portal?.filter((x) => (x.guid === guid) ?? []
tmpLevel.poi = tmpLevel.poi?.filter((x) => (x.guid === guid)) ?? []
return tmpLevel
} ?? []).map((poi) => poi.coordinate)
CodePudding user response:
Like @KiraLT mentioned it would be easier if you provided the desired input and output but one way you can handle this is by using reduce.
Background:
- In JS, functions are first-class, which means they can be passed around as arguments to other functions. (https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function)
- You can destructure values or properties from objects (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
- Reduce "walks through the array element-by-element, at each step adding the current array value to the result from the previous step (this result is the running sum of all the previous steps) — until there are no more elements to add." (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) In this case we can set an array of callback fns and the initial value the param that should be passed to your first fn.
- flatMap is basically map, then flat. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)
This is probably ~ same performance as your fn ^, so take it with a grain of salt.
function flatMapStoreItems() {
const guid = W/E
function filterPortals(items) {
return items.portals?.filter(({ guid: itemGuid }) => itemGuid == guid ?? [])
}
function filterPoi(items) {
return items.poi?.filter(({ guid: itemGuid }) => itemGuid == guid ?? [])
}
function mapCoordinates(items) {
return items.map(({ coordinate }) => coordinate)
}
function flat(items) {
return items.flat();
}
return [filterPortals, filterPoi, mapCoordinates, flat].reduce((fn), Object.values(state.storeLayout.items))
}
CodePudding user response:
This returns the desired result:
Object.values(state.storeLayout.items).flatMap((level) => {
let tmpLevel = {...level}
tmpLevel.portal = tmpLevel.portal?.filter((x) => (x.guid === guid) ?? []
tmpLevel.poi = tmpLevel.poi?.filter((x) => (x.guid === guid)) ?? []
return tmpLevel.poi.concat(tmpLevel.portals)
} ?? []).map((poi) => poi.coordinate)
Thanks everyone for reading and posting answers to help me out!