I'm trying to create a deep nested JS Object out of a simple array. The tricky part is that the next item in the array should always be added to the previous one.
Assuming my array looks like this:
const filters = [
[
{brand: {eq: 'BMW'}},
{brand: {eq: 'AUDI'}}
],
[
{year: {eq: '2019'}},
{year: {eq: '2020'}}
],
[
{country: {eq: 'CH'}},
{country: {eq: 'DE'}}
]
]
How can I get a Object with that structure?
query: {
and: {
or: [
{ brand: { eq: 'BMW' } },
{ brand: { eq: 'AUDI' } }
],
and: {
or: [
{ year: { eq: '2019' } },
{ year: { eq: '2020' } }
],
and: {
or: [
{ country: { eq: 'CH' } },
{ country: { eq: 'DE' } }
],
... and so on
}
}
}
},
How do I achieve to add a new "or" block to the previous "or" block?
2 Answers 2
You can build up a nested structure as you go through the array. For each item, add a nested object with an or key that links to the item and each following iteration work on the previous item
const filters = [
[
{brand: {eq: 'BMW'}},
{brand: {eq: 'AUDI'}}
],
[
{year: {eq: '2019'}},
{year: {eq: '2020'}}
],
[
{country: {eq: 'CH'}},
{country: {eq: 'DE'}}
]
]
const query = {};
let current = query;
for (const filter of filters) {
current.and = { or: filter };
current = current.and;
}
console.log(query);
3 Comments
for loop.reduce version isn't horrible but I find it quite unnecessary: query = {}; filters.reduce((current, filter) => { current.and = { or: filter }; return current.and}, query)reduce is basically a loop as the result is ignored. We can also shorten the for..of similarly: for (const or of filters) current = current.and = { or } Although, I guess the reduce can be golfed more.Just for the reduce challenge:
const filters = [
[
{brand: {eq: 'BMW'}},
{brand: {eq: 'AUDI'}}
],
[
{year: {eq: '2019'}},
{year: {eq: '2020'}}
],
[
{country: {eq: 'CH'}},
{country: {eq: 'DE'}}
]
];
const query = {};
filters.reduce((x, or) => x.and = { or }, query);
console.log(query);
Hacky as hell though:
reducewith side-effects- returns an assignment
VLAZ's approach is the way to go.