Reputation: 705
I have an array which is built from the user input. I am trying to loop through a nested key value pair and check whether the values in it matches any value of the given array. The purpose is to make a search facility.
My array :
FilteredSelectedOptions=["20180211","Trax","Vienna","AN01020"]
My key value pair is :
trips = {
"20180201": [{
"journeyId": 1001,
"Number": "001",
"DriverName": "Alex",
"Transporter": {
"id": "T1",
"number": "AN01001",
"Company": "Tranzient"
},
"place": [{
"id": 001,
"value": "Washington DC"
},
{
"id": 002,
"value": "Canberra"
}
],
},
{
"journeyId": 1002,
"Number": "001",
"DriverName": "Tom",
"Transporter": {
"id": "T2",
"number": "AN01002",
"Company": "Trax"
},
"place": [{
"id": 2,
"value": "Canberra"
},
{
"id": 4,
"value": "Vienna"
}
],
},
{
"journeyId": 1003,
"Number": "004",
"DriverName": "Jack",
"Transporter": {
"id": "T3",
"number": "AN01003",
"Company": "Trax"
},
"place": [{
"id": 1,
"value": "Washington DC",
}, {
"id": 4,
"value": "Vienna",
}],
}
],
"20180211": [{
"journeyId": 1004,
"Number": "005",
"DriverName": "Jack",
"Transporter": {
"id": "T3",
"number": "AN01013",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
},
{
"id": 4,
"value": "Vienna"
}
],
},
{
"journeyId": 1005,
"Number": "005",
"DriverName": "Jerry",
"Transporter": {
"id": "T3",
"number": "AN01020",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
}
],
}
],
"20180301": [{
"journeyId": 1006,
"Number": "005",
"DriverName": "demy",
"Transporter": {
"id": "T3",
"number": "AN01003",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
}
],
}],
};
I am expecting output like this :
trips = {
"20180201":
[{
"journeyId": 1002,
"Number": "001",
"DriverName":"Tom",
"Transporter": {
"id": "T2",
"number": "AN01002",
"Company": "Trax"
},
"place": [{"id":002,"value":"Canberra" }]
[{"id":004,"value":"Vienna"}]
},
{
"journeyId": 1003,
"Number": "004",
"DriverName":"Jack",
"Transporter": {
"id": "T3",
"number": "AN01003",
"Company": "Trax"
},
"place": [{"id":001,"value":"Washington DC" }]
[{"id":004,"value":"Vienna"}]
}],
"20180211": [{
"journeyId": 1004,
"Number": "005",
"DriverName":"Jack",
"Transporter": {
"id": "T3",
"number": "AN01013",
"Company": "Trax"
},
"place": [{"id":005,"value":"Bridgetown" }]
[{"id":006,"value":"Ottawa"}]
[{"id":004,"value":"Vienna"}]
},
{
"journeyId": 1005,
"Number": "005",
"DriverName": "Jerry",
"Transporter": {
"id": "T3",
"number": "AN01020",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
}
]
};
I am trying to use a for loop to check each array elements against the key value pair. What I want to do basically is
for (option in FilteredselectedOptions)
{
//logic
}
I have been able to do it for one particular array value:
const filteredTrips = Object.keys(trips).reduce((tmp, x) => {
const filtered = trips[x].filter(y => y.place && y.place.some(z => z.value === 'Vienna'));
if (filtered.length) {
tmp[x] = filtered;
}
return tmp;
}, {});
But how do I do it for all array elements irrespective of how many elements are inside array. Please help in the loop.
Upvotes: 1
Views: 224
Reputation: 386680
Just an approach by trying to filter with finding a single item in the data.
function filter(object, options) {
const check = v => options.includes(v) || v && typeof v === 'object' && Object.keys(v).some(l => check(v[l]));
var result = {};
Object.keys(object).forEach(function (k) {
var temp = options.includes(k)
? object[k]
: object[k].filter(check);
if (temp.length) {
result[k] = temp;
}
});
return result;
}
var trips = { "20180201": [{ journeyId: 1001, Number: "001", DriverName: "Alex", Transporter: { id: "T1", number: "AN01001", Company: "Tranzient" }, place: [{ id: "001", value: "Washington DC" }, { id: "002", value: "Canberra" }] }, { journeyId: 1002, Number: "001", DriverName: "Tom", Transporter: { id: "T2", number: "AN01002", Company: "Trax" }, place: [{ id: 2, value: "Canberra" }, { id: 4, value: "Vienna" }] }, { journeyId: 1003, Number: "004", DriverName: "Jack", Transporter: { id: "T3", number: "AN01003", Company: "Trax" }, place: [{ id: 1, value: "Washington DC" }, { id: 4, value: "Vienna" }] }], "20180211": [{ journeyId: 1004, Number: "005", DriverName: "Jack", Transporter: { id: "T3", number: "AN01013", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }, { id: 4, value: "Vienna" }] }, { journeyId: 1005, Number: "005", DriverName: "Jerry", Transporter: { id: "T3", number: "AN01020", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }] }], "20180301": [{ journeyId: 1006, Number: "005", DriverName: "demy", Transporter: { id: "T3", number: "AN01003", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }] }] },
options = ["20180211", /* "Trax", */ "Vienna", "AN01020"];
console.log(filter(trips, options));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 137
Let me know if you want a complete code. Lets begin that objects in javascript don't have built in filter or reduce methods, only arrays do. What I would do, I would loop through the object properties, which are arrays, and check if they have one of the properties that are found in the FilteredSelectedOptions. If I find one, I will push it to a new array containing the results.
Upvotes: 0
Reputation: 138417
One could use recursion to search for values in an object:
function hasValue(obj, values){
for(const value of Object.values(obj)){
if(typeof value === "object"){
if(hasValue(value, values))
return true;
} else {
if(values.includes(value))
return true;
}
}
return false;
}
Now we could filter your trips by comparing the keys and using the function above:
const filteredTrips = Object.keys(trips).filter(key => {
if(FilteredSelectedOptions.includes(key))
return true;
if(hasValue(trips[key], FilteredSelectedOptions))
return true;
return false;
});
Upvotes: 1