Reputation: 37361
I'm not seeing a way to find
objects when my condition would involve a nested array.
var modules = [{
name: 'Module1',
submodules: [{
name: 'Submodule1',
id: 1
}, {
name: 'Submodule2',
id: 2
}
]
}, {
name: 'Module2',
submodules: [{
name: 'Submodule1',
id: 3
}, {
name: 'Submodule2',
id: 4
}
]
}
];
This won't work because submodules
is an array, not an object. Is there any shorthand that would make this work? I'm trying to avoid iterating the array manually.
_.where(modules, {submodules:{id:3}});
Upvotes: 41
Views: 80463
Reputation: 231
If you want to search all by keyword:
const searchWord = 'Hello world'.trim().toLowerCase();
const result = JSON.stringify(object).trim().toLowerCase().includes(searchWord);
Upvotes: 0
Reputation: 61
Another solution can be:
const var = _.find(modules, (item) => {
return (item.submodules.id === 2)
})
You can either user _.find
to get the first occurrence or _.filter
to get all ot them.
Upvotes: 0
Reputation: 8970
I looked into this and I think the best option is to use Deepdash. It's a collection of methods to do deeply filter, find etc.
Sure it would be possible with lodash alone but with Deepdash it's easier.
I tried to convert the previous answer to the latest Lodash version but that was not working. Every method was deprecated in v4 of Lodash. Possible replacements: select = map or filter, any = some, where = filter)
findDeep
returns an object with some information to the found item (just some values, see the docs for more details):
value
is the object foundkey
that's the index in the nested arrayparent
the parent of the valueSo the code for the findDeep
looks like:
const modules = [{
name: 'Module1',
submodules: [{
name: 'Submodule1',
id: 1
}, {
name: 'Submodule2',
id: 2
}]
}, {
name: 'Module2',
submodules: [{
name: 'Submodule1',
id: 3
}, {
name: 'Submodule2',
id: 4
}]
}];
const getModule = (modules, id) =>
_.findDeep(modules, module => module.id === id, {
childrenPath: "submodules"
});
const resultEl = document.getElementById("result");
const foundModule = getModule(modules, 3).value;
resultEl.innerText = JSON.stringify(foundModule, null, 2);
<script src="https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script>
deepdash(_);
</script>
<h2>Example to get module with id = 3</h2>
<pre id="result"></pre>
Upvotes: 1
Reputation: 5458
Lodash allows you to filter in nested data (including arrays) like this:
_.filter(modules, { submodules: [ { id: 2 } ]});
Upvotes: 90
Reputation: 11211
Here's what I came up with:
_.find(modules, _.flow(
_.property('submodules'),
_.partialRight(_.some, { id: 2 })
));
// → { name: 'Module1', ... }
Using flow(), you can construct a callback function that does what you need. When call, the data flows through each function. The first thing you want is the submodules
property, and you can get that using the property() function.
The the submodules array is then fed into some(), which returns true if it contains the submodule you're after, in this case, ID 2
.
Replace find()
with filter()
if you're looking for multiple modules, and not just the first one found.
Upvotes: 28
Reputation: 907
I think your best chance is using a function, for obtaining the module.
_.select(modules, function (module) {
return _.any(module.submodules, function (submodule) {
return _.where(submodule, {id:3});
});
});
try this for getting the submodule
.where(.pluck(modules, "submodules"), {submodules:{id:3}});
Upvotes: 1