Reputation: 248
I am trying to filter non-array JSON object as the following snippet
const filter = { filterRows: ['one'] };
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
const filterDialogView = filter.filterRows;
const filterTemplateMapper = [templateMapper].filter(row => !filterDialogView.includes(row));
console.log(filterTemplateMapper);
But it's not filtering
I am getting following output
[
{
"one": {
"title": "one"
},
"two": {
"title": "two"
},
"three": {
"title": "three"
}
}
]
Desire output
{
"two": {
"title": "two"
},
"three": {
"title": "three"
}
}
I want to filter row based on filterRows
for example if filterRows contain one
as above JSON then one
should be removed from the templateMapper
Upvotes: 3
Views: 1318
Reputation: 272
You can use this way:
const filter = { filterRows: ['one'] };
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
// Convert object templateMapper to array with key
const keyArrayTemplateMapper = Object.keys(templateMapper);
// Filter key array
const filterKey = keyArrayTemplateMapper.filter(key => !filter.filterRows.includes(key));
// Using reduce method to return new array
const output = filterKey.reduce((obj, key) => {
obj[key] = templateMapper[key];
return obj;
}, {});
console.log(output);
Upvotes: 0
Reputation: 37775
You can use Object.fromEntries to build object back from filtered entries
Here idea is:-
const filter = { filterRows: ['one'] };
const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}}
const filterDialogView = filter.filterRows;
const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row))
console.log(Object.fromEntries(final));
If you environment doesn't support Object.fromEntries you can use this
const filter = { filterRows: ['one'] };
const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}}
const filterDialogView = filter.filterRows;
const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row))
const output = final.reduce((op,[key,value])=>{
op[key] = value
return op
},{})
console.log(output);
Upvotes: 4
Reputation: 36594
You can filter()
objects. You should filter()
the entries of object and then convert it to object again using Object.fromEntries()
const filter = { filterRows: ['one'] };
const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }
const filterDialogView = filter.filterRows;
const filterTemplateMapper = Object.fromEntries(
Object.entries(templateMapper)
.filter(row => !filterDialogView.includes(row[0].title))
);
console.log(filterTemplateMapper);
If Object.fromEntries()
is not supported by your browser then use reduce()
const filter = { filterRows: ['one'] };
const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }
const filterDialogView = filter.filterRows;
const filterTemplateMapper = Object.entries(templateMapper)
.filter(row =>!filterDialogView.includes(row[0].title))
.reduce((ac,[k,v]) => (ac[k] = v,ac),{});
console.log(filterTemplateMapper);
Upvotes: 0
Reputation: 91704
The filter()
function is only available on arrays. In order to get the same behaviour with an object, you need to use the object's entries()
.
const filter = {
filterRows: ['one']
}
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
const filteredMapper = Object.entries(templateMapper).reduce((acc, [key, value]) => {
// if the key is not in the filtered list, add this entry to the object
if (!filter.filterRows.includes(key)) {
acc[key] = value
}
return acc
}, {}) // pass in empty object as initial value of accumulator
console.log(filteredMapper)
The way this works is we first get the entries
(key/value pairs) from templateMapper
. We then take those entries and reduce
them. A reduce takes several arguments including an "accumulator" which is what collects the fields we want to keep. We "destructure" key
and value
so that we can check if the key is in the filter list. If it is not going to be filtered, we add it ot the accumulator. We then return the accumulator for the next iteration of the reduce. Finally, we pass in an empty object as the initial value for the accumulator on the first iteration.
Upvotes: -1
Reputation: 50346
Instead of modifying the original object create a copy of it and delete the unwanted keys. For delete you can use delete
keyword. Iterated the filterRows
array and then use delete
to remove the keys from the copied object
const filter = {
filterRows: ['one']
};
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three'
},
}
let newObj = JSON.parse(JSON.stringify(templateMapper));
filter.filterRows.forEach(function(item) {
if (newObj.hasOwnProperty(item)) {
delete newObj[item]
}
});
console.log(newObj)
Upvotes: -1
Reputation: 35259
You could filter
the entries
of the object first. Then use Object.fromEntries()
to create a new object from those filtered entries.
const filter = { filterRows: ['one'] };
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
}
const filteredObject = Object.fromEntries(
Object.entries(templateMapper).filter(([k]) => !filter.filterRows.includes(k))
)
console.log(filteredObject)
Upvotes: 2
Reputation: 371193
One option is to create a copy of the templateMapper
object, then iterate through the filterRows
and delete each associated key:
const filter = {
filterRows: ['one']
};
const templateMapper = {
'one': {
title: 'one',
},
'two': {
title: 'two',
},
'three': {
title: 'three',
},
};
const filterTemplateMapper = { ...templateMapper };
filter.filterRows.forEach((key) => {
delete filterTemplateMapper[key];
});
console.log(filterTemplateMapper);
(also, as comment notes, There's no such thing as a "JSON Object")
Upvotes: 1