Reputation: 219
I am trying to filter an array of arrays of objects, but it does not work.
constructNewGrid(filterText){
if(searchText == ""){
this.constructedGrid = this.fullGrid;
return;
}
this.constructedGrid = [];
this.constructedGrid = this.fullGrid.filter(array => array.filter(obj => {
if(obj.name == filterText)
return obj;
}));
console.log(this.constructedGrid);
}
I want to return an array of arrays with the correct object if found one but when I console log it constructedGrid
is the same array but why?
The code should go to the first array should look up whether there is an object with the name equals to the filter text it should return the array with the corrosponding object and then the next array should be checked and so on.
This, would be the format:
[
[[{name: string}], empty, empty], // array of lenth 3
[empty, empty, [{name: string}], empty], // array of length 4
...
]
If one object is found it should push it in an array separately such that if two objects where found in the same array, it should put them both in separately push them in two separat arrays and those should be in one single array: Result should be
[
[[obj1]],
[[obj2]],
...
]
It seems in possible for me. I got sometime an error that I am out of memory haha...
Upvotes: 0
Views: 1192
Reputation: 1074295
You'll need map
in addition to filter
, because filter
just decides whether to keep what's there, it doesn't change what's there. map
does. Something like this:
this.constructedGrid = this.fullGrid
// Map the inner array to one that only has matching entries
.map(array => array.filter(obj => obj && obj.name === filterText))
// Remove blank inner arrays from the overall array
.filter(array => array.length);
Live Example:
const fullGrid = [
[[{name: "target"}], , ],
[, null, [{name: "target"}], undefined],
];
const filterText = "target";
const constructedGrid = fullGrid
// Map the inner array to one that only has matching entries
.map(array => array.filter(obj => obj && obj[0] && obj[0].name === filterText))
// Remove blank inner arrays from the overall array
.filter(array => array.length);
console.log(constructedGrid);
.as-console-wrapper {
max-height: 100% !important;
}
Note that you only need that second filter
if you want to remove arrays that are completely empty from the outer array. If you want to leave them, just remove that call. Edit: From your reply to my question on the question, it sounds like you want to remove that second .filter
.
Note the guard in the first filter
, the obj && obj[0] &&
part. It's there because you said sometimes array entries are "empty." I don't know if you literally meant empty — a sparse array — or entries that are undefined
. If you literally meant empty (a sparse array), you don't need the guard, but it's probably best to have it.
As of ES2020, you could use the optional chaining operator instead:
.filter(obj => obj?.[0]?.name === filterText)
obj?.[0]?.name
evaluates to undefined
if obj
is null
or undefined
, or obj[0]
is null
or undefined
; it evaluates to obj[0].name
otherwise. Since undefined === filterText
will be false, entries with a null
or undefined
obj
will be left out. Again, though, new feature, you'll need to check support on your target browsers if you're not transpiling.
Upvotes: 1