I have the object with values. I trying to filter based on values.
var data = {
"map": {
"0": ["abcd"],
"1": ["efgh"],
"2": ["xyz"],
}
}
In above object I am trying to filter xyz which are have in array values.
Expecting output:
{ '0': [ 'xyz' ] }
I done the code but I am not sure it's efficient way. Can someone help me this.
const data = {
"map": {
"0": ["abcd"],
"1": ["efgh"],
"2": ["xyz"],
"3": ["abcd", "xyz"],
}
}
const filtered = Object.keys(data.map)
.filter((key) => {
return data.map[key].includes('xyz');
})
.reduce((obj, key, cIndex) => {
obj[cIndex] = data.map[key];
return obj;
}, {});
console.log('filtered', filtered);
2 Answers 2
Avoid use dictionary when you need Array
I'm not sure why you would prefer to store your Array-like data in a dictionary. I would suggest use a real Array if you need an Array.
Order of Object.keys
You may read more details about the order of Object.keys
return values from this post: Does ES6 introduce a well-defined order of enumeration for object properties? The order of Object.keys
is defined in ES2020. It may not work as you want in older environments.
Anyway, relay on the order of Object.keys
don't seems to be a good idea to me. You may always sort the keys after Object.keys
if you want though.
Use Object.assign
to convert to / from Array
When you need an Array, use an Array. You can try Object.assign
which convert your dictionary into Array and vice versa. (But this only applied to "when you cannot change the interface due to any reason").
function filterData(data, value) {
const arrayData = Object.assign([], data.map);
const filteredArrayData = arrayData.filter(list => list.includes(value));
const result = Object.assign({}, filteredArrayData);
return result;
}
-
\$\begingroup\$ Thanks for your response. When I add this in typescript I am getting error in includes.. Error details (Property 'includes' does not exist on type 'never'.ts(2339)) \$\endgroup\$RSKMR– RSKMR2021年01月22日 07:44:23 +00:00Commented Jan 22, 2021 at 7:44
-
\$\begingroup\$ @RSKMR Maybe you want to change your question to TypeScript? \$\endgroup\$tsh– tsh2021年01月22日 07:53:44 +00:00Commented Jan 22, 2021 at 7:53
-
\$\begingroup\$ Thanks @tsh for contributing this great answer - I hope to see more from you in future! \$\endgroup\$Toby Speight– Toby Speight2021年01月22日 07:57:29 +00:00Commented Jan 22, 2021 at 7:57
-
\$\begingroup\$ @RSKMR TypeScript seems not smart enough to know types correctly. So some internal variables may help. \$\endgroup\$tsh– tsh2021年01月22日 08:13:55 +00:00Commented Jan 22, 2021 at 8:13
Review
- the whole filter chain could be on basis of
value
instead ofkey
fromdata
since there's no real use of key here
filter
part
- technically your approach is perfect, just that it could be concise/readable
- you can simplify the
filter
as in below snippet, simply because readability is one of the TOP priority of a good code IMHO
map
part
instead of juggling the same
object
insidereduce
between all elements we can simply get the required objects out of it.one other major thing is that
reduce
as the name suggests is for when you wish to reduce N elements into exactly 1 element by some logic, which clearly isn't the case here & thus i thinkmap
should be preferred.we can use
map
here since at the end we want anarray
ofobject
s, so here we can returnobject
for each key which at end gets collected asarray
apart from these the redability point again applies here as well, since this can also be simplified very much, refer the snippet to get an idea
quoting a point from Mozilla's doc on
reduce
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.
Alternate approach
const data = {
"map": {
"0": ["abcd"],
"1": ["efgh"],
"2": ["xyz"],
"3": ["abcd", "xyz"],
}
}
const filtered = Object.values(data.map)
.filter(value => value.includes('xyz'))
// the () after the "=>" are used to wrap returned result into object
// the [i] inside ({..}) is used for setting the key dynamically
.map((value, i) => ({[i]: value}));
console.log('filtered', filtered);
- The data structure seems to be object representation of
array
, so if possible prefer2D array
overobject
with 0 based keys, this would make things more simple
PS: answer is updated after useful suggestions of @Toby Speight & @Graipher in comments
-
1\$\begingroup\$ You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer. \$\endgroup\$Toby Speight– Toby Speight2021年01月22日 07:56:50 +00:00Commented Jan 22, 2021 at 7:56
-
2\$\begingroup\$ @TobySpeight Well, there is some review here, it is just hidden in the comments in the code. This would be a lot better answer if you pulled it out of the comments and put it into text, Harsh Gundecha. \$\endgroup\$Graipher– Graipher2021年01月22日 11:00:12 +00:00Commented Jan 22, 2021 at 11:00
-
\$\begingroup\$ I easily miss comments in the code; I too prefer descriptive text outside of the code block. That's easier to tell apart from a review focusing on the commenting of the code, for one thing. \$\endgroup\$Toby Speight– Toby Speight2021年01月22日 11:07:23 +00:00Commented Jan 22, 2021 at 11:07
Explore related questions
See similar questions with these tags.
0
ton
, and the order should also be kept in output? \$\endgroup\$