Reputation: 4170
I have the following data structure:
[
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
]
i.e., a list of objects. Inside these objects, there is another list: waivers
. My question is, how would I filter the list waivers
inside the list of objects, such that, if I filtered by, e.g., a ticketID of 63152
, I'd receive the following returned:
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
}
]
}
]
Assuming the original data structure is stored as this.activeSurfersWaivers
, I have tried the following:
const todaysWaivers = this.activeSurfersWaivers.filter((surfersWaivers) => {
surfersWaivers.waivers.filter((surferWaiver) => {
return (surferWaiver.ticketId.indexOf(this.searchedTicketID) >= 0);
});
});
Which returns an empty array for a value of this.searchedTicketID
of 63152. Any pro-tips on filtering this awkward data structure would be greatly appreciated!
Upvotes: 1
Views: 114
Reputation: 50787
Although these techniques are very similar to those in the answer by connexo, I find it cleaner to make a reusable function. This is what I came up with:
const matchingPerformances = (data, id) => data
.filter (({waivers}) => waivers .some (({ticketId}) => ticketId == id))
.reduce ((a, {waivers, ... r}) => [
... a,
{... r, waivers: waivers .filter (({ticketId}) => ticketId == id)}
], [])
const data = [{performanceDatetime: "2020-01-28T08: 00: 00Z", waivers: [{ticketId: "66288"}]}, {performanceDatetime: "2020-01-28T08: 30: 00Z", waivers: [{ticketId: "63152"}, {ticketId: "66113"}]}, {performanceDatetime: "2020-01-28T09: 00: 00Z", waivers: [{ticketId: "62667"}]}]
console .log (matchingPerformances (data, "63152"))
If I wanted to clean up some duplication, I might add a helper function:
const ticketMatch = (id) => ({ticketId}) => ticketId == id
const matchingPerformances = (data, id) => data
.filter (({waivers}) => waivers .some (ticketMatch (id)))
.reduce ((a, {waivers, ... r}) => [
... a,
{... r, waivers: waivers .filter (ticketMatch (id))}
], [])
While this could be done in a single reduce
call, I think that would end up being much harder code to understand.
Upvotes: 0
Reputation: 17
I hope this solution is what you are looking for. It takes care of instances where
there are multiple waivers
array entries.
var dataStructure =
[
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
];
function filterDataStructureByWaiverTicketId(ticketId)
{
return dataStructure.filter(function (value, index, array)
{
//find index in the "waivers" array where ticketId occurs
var waiverIndex = value.waivers.reduce(function(a, e, i)
{
if (e.ticketId === ticketId)
{
a.push(i);
}
return a;
}, []);
if(waiverIndex.length > 0)//if a match exists
{ //remove everything in the "waivers" array that does not match
var newWaivers = value.waivers.filter(function (value, index, array)
{
return value.ticketId === ticketId;
});
value.waivers = newWaivers;//replace the old waivers array with the new one that matches
return value.waivers[0].ticketId === ticketId;//tadaa...
}
});
}
Usage example:
Example 1:
var newdatastructure = filterDataStructureByWaiverTicketId("66113");/*
newdatastructure[0].performanceDatetime //returns "2020-01-28T08:30:00Z"
newdatastructure[0].waivers[0].ticketId //returns "66113"
newdatastructure //returns
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "66113",
}
]
}
]*/
Example 2:
var newdatastructure = filterDataStructureByWaiverTicketId("63152");/*
newdatastructure[0].performanceDatetime //returns "2020-01-28T08:30:00Z"
newdatastructure[0].waivers[0].ticketId //returns "63152"
newdatastructure // returns
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
}
]
}
]*/
Example 3:
var newdatastructure = filterDataStructureByWaiverTicketId("66288");/*
newdatastructure[0].performanceDatetime //returns "2020-01-28T08:00:00Z"
newdatastructure[0].waivers[0].ticketId //returns "66288"
newdatastructure //returns
[
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
}
]
}
]*/
Upvotes: 0
Reputation: 11001
UPDATE: Adding multiple ways to do.
reduce
method. (find_item method)for of
loop. (find_item2 method)const find_item = (arr, searchId) =>
arr.reduce((acc, curr) => {
const waivers = curr.waivers.filter(waiver => waiver.ticketId === searchId);
return waivers.length > 0 ? [{ ...acc, ...curr, waivers }] : [...acc];
}, []);
const find_item2 = (arr, searchId) => {
for (let curr of arr) {
const waivers = curr.waivers.filter(waiver => waiver.ticketId === searchId);
if (waivers.length > 0) {
return [{ ...curr, waivers }];
}
}
return [];
};
const arr = [
{
performanceDatetime: "2020-01-28T08:00:00Z",
waivers: [
{
ticketId: "66288"
}
]
},
{
performanceDatetime: "2020-01-28T08:30:00Z",
waivers: [
{
ticketId: "63152"
},
{
ticketId: "66113"
}
]
},
{
performanceDatetime: "2020-01-28T09:00:00Z",
waivers: [
{
ticketId: "62667"
}
]
}
];
const searchId = "66113";
console.log(find_item(arr, searchId));
console.log(find_item2(arr, searchId));
Upvotes: -1
Reputation: 56754
This is what I would do if I had to rush it:
const data = [{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [{
"ticketId": "66288",
}, ]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [{
"ticketId": "62667",
}, ]
}
]
const idToFind = "63152";
const matchingEntries = data.filter(entry => entry.waivers.some(el => el.ticketId === idToFind));
matchingEntries.forEach(entry => entry.waivers = entry.waivers.filter(el => el.ticketId === idToFind));
console.log(matchingEntries);
This returns
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152"
}
]
}
]
Upvotes: 2
Reputation: 1193
You are actually very close. You'll want to check if the second filter yields any results:
data = [
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
];
const filter = ticket => {
return data.filter(entry => {
return entry.waivers.some(waiver => waiver.ticketId === ticket)
}).map(entry => {
entry.waivers = entry.waivers.filter(waiver => waiver.ticketId === ticket);
return entry;
});
};
console.log(filter("63152"));
Upvotes: 1
Reputation: 959
Here is how you do it:
https://codepen.io/v08i/pen/KKwYrRp
<div id="test1">
</div>
<div id="test2">
</div>
let arr = [
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
]
function findItem(id) {
return arr.find((item) => {
return item.waivers.some((waiver) => { return waiver.ticketId == id});
});
}
document.getElementById('test1').innerHTML = JSON.stringify(findItem('63152'));
document.getElementById('test2').innerHTML = JSON.stringify(findItem('62667'));
console.log(findItem('63152'));
console.log(findItem('62667'));
Upvotes: 1