Group arrays by parent ids object Ramda - javascript

Need a help from Ramda community... I have an object array that I need to sort by "chapter_id" and after sorting, just remove "chapter_id":
const stuff = [
{ id: 1, title: "hello world", chapter_id: "4321" },
{ id: 2, title: "new title", chapter_id: "21" },
{ id: 3, title: "...", chapter_id: "33" },
{ id: 4, title: "huh!?", chapter_id: "14" },
{ id: 5, title: "From Earth", chapter_id: "11" },
{ id: 6, title: "alien", chapter_id: "11" },
{ id: 7, title: "Saturn", chapter_id: "11" },
{ id: 8, title: "Mars:/", chapter_id: "21" },
{ id: 9, title: "damn", chapter_id: "3" },
{ id: 10, title: "test", chapter_id: "11" },
{ id: 11, title: "ramda heeeelp", chapter_id: "31" },
{ id: 12, title: "hello?", chapter_id: "21" }
]
And as result I want to get this object:
{
"3": [
{
"id": "9",
"title": "damn"
}
],
"11": [
{
"id": "5",
"title": "From Earth"
},
{
"id": "6",
"title": "alien"
},
{
"id": "7",
"title": "Saturn"
},
{
"id": "10",
"title": "test"
}
],
"14": [
{
"id": "4",
"title": "huh!?"
}
],
"21": [
{
"id": "2",
"title": "new title"
},
{
"id": "8",
"title": "Mars:/"
},
{
"id": "12",
"title": "hello?"
}
],
"31": [
{
"id": "11",
"title": "ramda heeeelp"
}
],
"33": [
{
"id": "3",
"title": "..."
}
],
"4321": [
{
"id": "1",
"title": "hello world"
}
]
}
How I struggled with this:
let object = {};
map(({ chapter_id }) => {
const composed = compose(
map(evolve({ id: toString })), //here id is converted to a string
filter(c => c.chapter_id === chapter_id),
);
object[chapter_id] = composed(stuff)
}, stuff);
My result:
{
"3": [
{
"id": "9",
"title": "damn",
"chapter_id": "3" //Dissoc this
}
],
"11": [
{
"id": "5",
"title": "From Earth",
"chapter_id": "11" //dissoc this
},
{
"id": "6",
"title": "alien",
"chapter_id": "11" //and this
},
{
"id": "7",
"title": "Saturn",
"chapter_id": "11" //and this
},
{
"id": "10",
"title": "test",
"chapter_id": "11" //and this
}
],
"14": [
{
"id": "4",
"title": "huh!?",
"chapter_id": "14" //and this
}
],
"21": [
{
"id": "2",
"title": "new title",
"chapter_id": "21" //and this
},
{
"id": "8",
"title": "Mars:/",
"chapter_id": "21" //and this
},
{
"id": "12",
"title": "hello?",
"chapter_id": "21" //and this
}
],
"31": [
{
"id": "11",
"title": "ramda heeeelp",
"chapter_id": "31" //and this!!!!!!
}
],
"33": [
{
"id": "3",
"title": "...",
"chapter_id": "33" //and this..
}
],
"4321": [
{
"id": "1",
"title": "hello world",
"chapter_id": "4321" //and this:(
}
]
}
It works but I can't dissoc "chapter_id" from each object, does anyone know how to solve this? :Δ

With Ramda you can group by the key, and then map the groups, and dissoc the key from all objects:
const { pipe, groupBy, prop, map, dissoc } = R;
const fn = key => pipe(
groupBy(prop(key)), // group by the key
map(map(dissoc(key))) // remove the key from all objects in all groups
);
const stuff = [{"id":1,"title":"hello world","chapter_id":"4321"},{"id":2,"title":"new title","chapter_id":"21"},{"id":3,"title":"...","chapter_id":"33"},{"id":4,"title":"huh!?","chapter_id":"14"},{"id":5,"title":"From Earth","chapter_id":"11"},{"id":6,"title":"alien","chapter_id":"11"},{"id":7,"title":"Saturn","chapter_id":"11"},{"id":8,"title":"Mars:/","chapter_id":"21"},{"id":9,"title":"damn","chapter_id":"3"},{"id":10,"title":"test","chapter_id":"11"},{"id":11,"title":"ramda heeeelp","chapter_id":"31"},{"id":12,"title":"hello?","chapter_id":"21"}];
const result = fn('chapter_id')(stuff);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

As Ori Drori notes, this is the likely Ramda method:
const transform = pipe (
groupBy(prop('chapter_id')),
map(map(dissoc('chapter_id'))),
)
But if you need to actually sort the keys, as your answer suggests, then it will take a bit more processing. You might try something like this:
const transform = pipe (
groupBy(prop('chapter_id')),
map(map(dissoc('chapter_id'))),
toPairs,
sortBy(pipe(head, Number)),
fromPairs
)
const stuff = [{id: 1, title: "hello world", chapter_id: "4321"}, {id: 2, title: "new title", chapter_id: "21"}, {id: 3, title: "...", chapter_id: "33"}, {id: 4, title: "huh!?", chapter_id: "14"}, {id: 5, title: "From Earth", chapter_id: "11"}, {id: 6, title: "alien", chapter_id: "11"}, {id: 7, title: "Saturn", chapter_id: "11"}, {id: 8, title: "Mars: /", chapter_id: "21"}, {id: 9, title: "damn", chapter_id: "3"}, {id: 10, title: "test", chapter_id: "11"}, {id: 11, title: "ramda heeeelp", chapter_id: "31"}, {id: 12, title: "hello?", chapter_id: "21"}]
console.log (
transform (stuff)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script> const {pipe, groupBy, prop, map, dissoc, toPairs, sortBy, head, fromPairs} = R </script>
That sorting line could be written in many ways. Perhaps
sort(lift(subtract)(head, head)),
or just
sort(([a], [b]) => a - b),
And obviously if you were so inclined, you could pull out a sortByKeys function like this:
const sortByKeys = (fn) => pipe(toPairs, sortBy(fn), fromPairs)
sortByKeys is not a likely candidate for inclusion in Ramda, which really prefers to think of objects as unordered collections of name-value pairs. But it could easily go in your own helper library.

First of all the finite task is not properly described :) What you really want (based on the result I want to get section) is to normalize (or restructure) the array of objects into an object, which have the chapter_id as a key, and the value is an array of the associated records of the stuff array with that chapter_id
On my opinion, your solution is cool and seems like a more functional, but in this particular case I've probably will give a preference to the simple reduce function, which is more readable...
reduce((acc, {chapter_id, ...rest}) => {
const isInitialized = !!acc[chapter_id];
if (isInitialized) {
acc[chapter_id].push(rest);
} else {
acc[chapter_id] = [rest];
}
return acc;
}, {}, stuff);

Related

Group nested objects with reduce

I have an array with objects
const data = [{
"id": 19887003,
"category": "Shops",
"details": "Shoe Store",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 19234003,
"category": "Shops",
"details": "Shoe Point",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 190456003,
"category": "Food",
"details": "Korean",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 190111003,
"category": "Food",
"details": "Chinese",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 1902303,
"category": "Food",
"details": "Lounge",
"star": 4,
"subCategory": "Bar",
}]
this is a small piece but the structure is the same for all objects: i have a category, with multiple subcategories and sometimes the subcategory has details..for example the category food has the subcategory restourant and restourant has many types (chinese, korean).
My goal is to get a structure like that:
[
{
"category": "Food",
"subCategories": [
{
"Subcategory": "Bar",
"details": [
{
name: "Lounge",
star: 2,
id: 1902303
}
]
},
{
"Subcategory": "Restaurant",
"details": [
{
name: "Chinese",
star: 4,
id: 190111003
},
{
name: "Korean",
star: 4,
id: 190456003
}
]
}
},
{
"category": "Shops",
"subCategories": [
{
"Subcategory": "Outlet",
"details": [
{
name: "Shoe Store",
star: 2,
id: 19887003
},
{
name: "Shoe Point",
star: 2,
id: 19234003
}
]
}
]
}
]
My attempt:
const groupedCategories = data.reduce((accumulator, element) => {
const detail = element.details;
const category = element.category;
const subCategory = element.subCategory;
if (accumulator[category]){
return {
...accumulator,
[category]: {
...accumulator[category],
subCategories: [...new Set([...accumulator[category].subCategories,subCategory])],
}
}}
else {
return {
...accumulator,
[category]: {
subCategories: [subCategory],
}
}
}
}, {});
I tried use reduce method like that but this is not the exact structure I desire in particular how to put details fields into subcategories.
Thanks
array.reduce seems to be the right choice. Simplest approach is to have double if statement to check if previous element (category and subcategory exists) and either push into existing array or create new object on upper level:
const data = [{
"id": 19887003,
"category": "Shops",
"details": "Shoe Store",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 19234003,
"category": "Shops",
"details": "Shoe Point",
"star": 2,
"subCategory": "Outlet",
},
{
"id": 190456003,
"category": "Food",
"details": "Korean",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 190111003,
"category": "Food",
"details": "Chinese",
"star": 4,
"subCategory": "Restaurant",
},
{
"id": 1902303,
"category": "Food",
"details": "Lounge",
"star": 4,
"subCategory": "Bar",
}]
let output = data.reduce((acc,cur) => {
let {category, subCategory, ...rest} = cur;
let prevCat = acc.find(x => x.category === category);
if(!prevCat){
acc.push({category, subCategories: [{subCategory, details: [rest]}]});
} else {
let prevSubCat = prevCat.subCategories.find(x => x.subCategory === subCategory);
if(!prevSubCat) {
prevCat.subCategories.push({subCategory, details: [rest]});
} else {
prevSubCat.details.push(rest);
}
}
return acc;
}, []);
console.log(output);

What is the best way to group this js array items in this structure

how can i convert returned data from this structure:
[
{
"id": 91,
"name": "Art",
"division": {
"id": 4,
"name": "1st level",
"created_at": "2018-11-05T10:11:37+00:00",
},
"created_at": "2018-11-05T10:11:37+00:00",
},
{
"id": 188,
"name": "English",
"division": {
"id": 9,
"name": "3rd level",
"created_at": "2018-11-05T10:11:37+00:00",
},
"created_at": "2018-11-05T10:11:37+00:00",
},
{
"id": 218,
"name": "Art",
"division": {
"id": 11,
"name": "3rd level",
"created_at": "2018-11-05T10:11:37+00:00",
},
"created_at": "2018-11-05T10:11:37+00:00",
}
]
to this structure :
[
{
"id": 1,
"name": "Art",
"classes": [
{
"id": 91,
"name": "1st level",
},
{
"id": 218,
"name": "3rd level",
},
],
},
{
"id": 2,
"name": "English",
"classes": [
{
"id": 188,
"name": "3rd level",
},
],
},
]
note: class.id = parentSubject.id
I wrote some codes to solve the problem but I'm looking for the best way !!
i use .reduce() function
I will attach the codes in the comments box.
Here is how I would do it:
let ans = initialArray.reduce((cum,x) => {
let foundIndex = cum.findIndex((a) =>{
return a.name == x.name});
if(foundIndex!=-1){
cum[foundIndex].classes.push({
id : x.id,
name : x.division.name
})
}
else{
cum.push({
id : cum.length+1,
name : x.name,
classes : [{
id : x.id,
name : x.division.name
}]
})
}
return cum;
},[]);
I use reduce and findIndex methods.
You can use array map to create a new array of objects with the new id.
const oldDatas = [
{
id: 91,
name: 'Art',
division: {
id: 4,
name: '1st level',
created_at: '2018-11-05T10:11:37+00:00',
},
created_at: '2018-11-05T10:11:37+00:00',
},
{
id: 188,
name: 'English',
division: {
id: 9,
name: '3rd level',
created_at: '2018-11-05T10:11:37+00:00',
},
created_at: '2018-11-05T10:11:37+00:00',
},
{
id: 218,
name: 'Art',
division: {
id: 11,
name: '3rd level',
created_at: '2018-11-05T10:11:37+00:00',
},
created_at: '2018-11-05T10:11:37+00:00',
},
];
const newDatas = oldDatas.map((data, index) => {
return { ...data, id: index + 1 };
});
console.log(newDatas);
my solution :
let res = initialArray.reduce((acc, obj) => {
const exist = acc.findIndex((item) => item.name === obj.name);
if (exist >= 0) {
acc[exist] = {
id: exist,
name: obj.name,
classes: [
...acc[exist].classes,
{ id: obj.id, name: obj.division.name },
],
};
} else {
acc.push({
id: acc.length,
name: obj.name,
classes: [{ id: obj.id, name: obj.division.name }],
});
}
return acc;
}, []);

Nested Array Filter/Mapping

Probably a basic question, but I've been blocked for a day now on this.
I am trying to get the correct map/filter from the following array:
[{
"id": 1,
"description": "Electric",
"subUtilityTypes": [{
"id": 5,
"description": "Grid"
},
{
"id": 6,
"description": "Solar"
}
]
},
{
"id": 2,
"description": "Gas",
"subUtilityTypes": [{
"id": 7,
"description": "Heating Oil"
},
{
"id": 8,
"description": "Natural Gas"
},
{
"id": 11,
"description": "Propane"
}
]
}
]
I want to get the id and description inside all subUtilityTypes.
This is what I've been trying:
this.options = arr1.map((parent) => {
return {
id: parent.id,
name: parent.subUtilityTypes.flatMap((child) => {
return child.description;
})
};
});
My problem with what I am trying is that instead of creating separate objects I am getting parent id and list of child names like this:
[{
"id": 1,
"name": [
"Grid",
"Solar"
]
},
{
"id": 2,
"name": [
"Heating Oil",
"Natural Gas",
"Propane"
]
}
]
Expected result should look like this:
[{
"id": 5,
"name": [
"Grid"
]
},
{
"id": 6,
"name": [
"Solar"
]
},
{
"id": 7,
"name": [
"Heating Oil"
]
}
]
Firstly use flatMap to get subUtilityTypes, then map entries:
const input = [{id:1,description:"Electric",subUtilityTypes:[{id:5,description:"Grid"},{id:6,description:"Solar"}]},{id:2,description:"Gas",subUtilityTypes:[{id:7,description:"Heating Oil"},{id:8,description:"Natural Gas"},{id:11,description:"Propane"}]}];
const res = input.flatMap(e => e.subUtilityTypes)
.map(e => ({ id: e.id, name: [e.description] }))
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */
Map only arr1 by returning only subUtilityTypes and then map it to get the desired result :
arr1.flatMap(item=>item.subUtilityTypes)
.map(item=>({id:item.id,name:[item.description]}))
let arr1=[
{
"id": 1,
"description": "Electric",
"subUtilityTypes": [
{
"id": 5,
"description": "Grid"
},
{
"id": 6,
"description": "Solar"
}
]
},
{
"id": 2,
"description": "Gas",
"subUtilityTypes": [
{
"id": 7,
"description": "Heating Oil"
},
{
"id": 8,
"description": "Natural Gas"
},
{
"id": 11,
"description": "Propane"
}
]
}
]
let options=arr1.flatMap(item=>item.subUtilityTypes).map(item=>({id:item.id,name:[item.description]}))
console.log(options)
You can also use reduce to achieve the same result.
arr.reduce((acc, curr) => [...acc,...curr.subUtilityTypes.map((o) => ({ id: o.id, name: [o.description] })),],[])
const arr = [
{
id: 1,
description: "Electric",
subUtilityTypes: [
{
id: 5,
description: "Grid",
},
{
id: 6,
description: "Solar",
},
],
},
{
id: 2,
description: "Gas",
subUtilityTypes: [
{
id: 7,
description: "Heating Oil",
},
{
id: 8,
description: "Natural Gas",
},
{
id: 11,
description: "Propane",
},
],
},
];
const result = arr.reduce((acc, curr) => [...acc,...curr.subUtilityTypes.map((o) => ({ id: o.id, name: [o.description] })),],[]);
console.log(result);

Changing arrays using map in javascript

This is my json object:
{
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
}
I want my output like this:
{
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"cats": [1,2] // this 1 and 2 is coming from categoriesservices array inside the category object i have id
}
How to do this using map function? I am new to javascript, which is good approach map or forloop?
See destructuring assignment, Array.prototype.map(), and JSON for more info.
// Input.
const input = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
}
// Categories => Objects to Cats => Ids.
const output = (input) => JSON.parse(JSON.stringify({
...input,
cats: input.categoryservices.map(({category: {id}}) => id),
categoryservices: undefined
}))
// Log.
console.log(output(input))
If you are not worried about original object immutability, then try this
obj['cats'] = obj['categoryservices'].map(cat => cat.category.id);
delete obj['categoryservices'];
console.log(obj);
I just use .map() on categoryservices array:
var output = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
};
output.cats = output.categoryservices.map((element) =>
element.category.id);
delete output.categoryservices;
console.log(JSON.stringify(output));
use .map() , it return value as array ! You want to change is categoryservices key only ! So delete that after you get wanted value ..
var output = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
};
output.cats = output.categoryservices.map(i => i.category.id );
delete output.categoryservices;
console.log(output);
Try this working demo :
var jsonObj = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
};
var arr = jsonObj.categoryservices.map(item => item.category.id)
jsonObj.cats = arr;
delete jsonObj.categoryservices;
console.log(jsonObj);
Try this
var testData={
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
}
testData.cats=[];
testData.categoryservices.forEach(function (item) {
testData.cats.push(item.category.id);
});
delete testData.categoryservices;
console.log(testData);
You can try using jquery each:
<div id="log"></div>
var conversation = {
'John': {
1: 'Test message 1',
2: 'Test message 2',
'Reply': {
3: 'Test message 3',
4: 'Test message 4'
}
},
'Jack': {
5: 'Test message 5',
6: 'Test message 6'
}
};
function iterate(obj) {
if (typeof obj === 'string') {
$('#log').append((obj + '<br/>'));
}
if (typeof obj === 'object') {
$.each(obj, function(key, value) {
iterate(value);
});
}
}
iterate(conversation);

How to loop through a nested key value pair and filter it based on a array values

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.
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; }
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;
});
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.

Categories