Stack Overflow Asked by user12097954 on January 5, 2022
I am currently manually looping through an array and doing deeper and deeper nested loops to compare values, but I am curious if there is any way to do this search automatically? I need to find deep nested arrays, compare 1 or 2 values and then also be able to modify the values.
Example array.
searchableArray = [];
searchableArray.push({id: 3, type: 'some-type', text: 'text', nestedElements: [{id: 4, type: 'some-type', text: 'other text', nestedElements: []}, {id: 5, type: 'another-type', text: 'more text', nestedElements: []}]})
searchableArray.push({id: 6, type: 'other-type', text: 'text', nestedElements: [{id: 7, type: 'other-type', text: 'other text', nestedElements: []}, {id: 8, type: 'another-type', text: 'more text', nestedElements: []}]})
searchableArray.push({id: 9, type: 'another-type', text: 'text', nestedElements: [{id: 10, type: 'another-type', text: 'other text', nestedElements: []}, {id: 11, type: 'another-type', text: 'more text', nestedElements: []}]})
Basically I need to search for id (It will be unique throughout the entire array and object, but could be nested various levels deep inside an object inside another array. But will always be called "nestedElements".
I need to be able to find the ID and then modify the object that ID belongs too and put it back in the array I am using.
Right now I am just making manual loops for each potential nested array. (Which is a lot of extra copy paste code)
for(var i = 0; i < searchableArray.length; ++i)
{
if(searchableArray[i].id == 6) //6 would actually be a variable, just doing a manual example
{
if(searchableArray[i].nestedElements.length > 0)
{
for(var j = 0; j < searchableArray[i].nestedElements.length; ++j)
{
if(searchableArray[i].nestedElements[j].id == '7')
{
if(searchableArray[i].nestedElements[j].type == 'other-type')
{
searchableArray[i].nestedElements[j].dosomething = 'do this to something in the object';
}
else if(searchableArray[i].nestedElements[j].type == 'another-type')
{
searchableArray[i].nestedElements[j].dosomething = 'do this other thing to the object';
}
}
}
}
}
}
This would get very huge with nested loops for everything, so is there any easier way to do it?
Thanks!
We try not to reinvent too much these days and I'd suggest object-scan for this. It's pretty powerful once you wrap your head around it. Here is how you'd use it:
// const objectScan = require('object-scan');
const modify = (id, task, data) => objectScan(['**.id'], {
abort: true,
rtn: 'bool',
filterFn: ({ value, parent }) => {
if (value === id) {
task(parent);
return true;
}
return false;
}
})(data);
const searchableArray = [{ id: 3, type: 'some-type', text: 'text', nestedElements: [{ id: 4, type: 'some-type', text: 'other text', nestedElements: [] }, { id: 5, type: 'another-type', text: 'more text', nestedElements: [] }] }, { id: 6, type: 'other-type', text: 'text', nestedElements: [{ id: 7, type: 'other-type', text: 'other text', nestedElements: [] }, { id: 8, type: 'another-type', text: 'more text', nestedElements: [] }] }, { id: 9, type: 'another-type', text: 'text', nestedElements: [{ id: 10, type: 'another-type', text: 'other text', nestedElements: [] }, { id: 11, type: 'another-type', text: 'more text', nestedElements: [] }] }];
console.log(modify(7, (obj) => {
if (obj.type === 'other-type') {
obj.dosomething = 'do this to something in the object';
} else if (obj.type === 'another-type') {
obj.dosomething = 'do this other thing to the object';
}
}, searchableArray)); // true iff executed
// => true
console.log(searchableArray);
// => [ { id: 3, type: 'some-type', text: 'text', nestedElements: [ { id: 4, type: 'some-type', text: 'other text', nestedElements: [] }, { id: 5, type: 'another-type', text: 'more text', nestedElements: [] } ] }, { id: 6, type: 'other-type', text: 'text', nestedElements: [ { id: 7, type: 'other-type', text: 'other text', nestedElements: [], dosomething: 'do this to something in the object' }, { id: 8, type: 'another-type', text: 'more text', nestedElements: [] } ] }, { id: 9, type: 'another-type', text: 'text', nestedElements: [ { id: 10, type: 'another-type', text: 'other text', nestedElements: [] }, { id: 11, type: 'another-type', text: 'more text', nestedElements: [] } ] } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>
Disclaimer: I'm the author of object-scan
Answered by vincent on January 5, 2022
This is what you want:
const searchableArray = [];
searchableArray.push({ id: 3, type: 'some-type', text: 'text', nestedElements: [{ id: 4, type: 'some-type', text: 'other text', nestedElements: [] }, { id: 5, type: 'another-type', text: 'more text', nestedElements: [] }] })
searchableArray.push({ id: 6, type: 'other-type', text: 'text', nestedElements: [{ id: 7, type: 'other-type', text: 'other text', nestedElements: [] }, { id: 8, type: 'another-type', text: 'more text', nestedElements: [] }] })
searchableArray.push({ id: 9, type: 'another-type', text: 'text', nestedElements: [{ id: 10, type: 'another-type', text: 'other text', nestedElements: [] }, { id: 11, type: 'another-type', text: 'more text', nestedElements: [] }] });
const find = (id, cb) => {
const ar = searchableArray.slice(0);
for (var i = 0; i < ar.length; i++) {
if (ar[i].id === id) {
return cb(ar[i]);
}
if (ar[i].nestedElements.length) {
ar.push(...ar[i].nestedElements);
}
}
}
find(7, (o) => {
if (o.type == 'other-type') {
o.dosomething = 'do this to something in the object';
} else if (o.type == 'another-type') {
o.dosomething = 'do this other thing to the object';
}
});
console.log(JSON.stringify(searchableArray));
Answered by 8HoLoN on January 5, 2022
You can simplify your structure by some code refactoring:
if
can be avoided by &&
operator.for
loop and use find instead.let searchableArray = [];
searchableArray.push({id: 3, type: 'some-type', text: 'text', nestedElements: [{id: 4, type: 'some-type', text: 'other text', nestedElements: []}, {id: 5, type: 'another-type', text: 'more text', nestedElements: []}]})
searchableArray.push({id: 6, type: 'other-type', text: 'text', nestedElements: [{id: 7, type: 'other-type', text: 'other text', nestedElements: []}, {id: 8, type: 'another-type', text: 'more text', nestedElements: []}]})
searchableArray.push({id: 9, type: 'another-type', text: 'text', nestedElements: [{id: 10, type: 'another-type', text: 'other text', nestedElements: []}, {id: 11, type: 'another-type', text: 'more text', nestedElements: []}]})
searchableArray.forEach(item => {
if(item.id === 6 && item.nestedElements.length > 0 && item.nestedElements.find(item => item.id === 7 && item.type === "other-type")){
item.nestedElements.find(item => item.id === 7 && item.type === "other-type").dosomething = 'do this to something in the object';
} else if (item.id === 6 && item.nestedElements.length > 0 && item.nestedElements.find(item => item.id === 7 && item.type === "another-type")){
item.nestedElements.find(item => item.id === 7 && item.type === "another-type").dosomething = 'do this other thing to the object';
}
});
console.log(searchableArray);
Answered by Ravi Kukreja on January 5, 2022
Example:
searchableArray.forEach(function(el){
if (el.hasOwnProperty("nestedElements") && el.nestedElements instanceof Array){
el.nestedElements.forEach(function(el1){
if (el1.id===7){
}
});
}
});
Answered by toto on January 5, 2022
4 Asked on December 5, 2021 by cow
0 Asked on December 5, 2021 by nippledisaster
2 Asked on December 5, 2021 by chalupabatmac
1 Asked on December 5, 2021 by prateek-singh
2 Asked on December 5, 2021 by robert-little
1 Asked on December 5, 2021 by user49404
1 Asked on December 5, 2021 by cosimoth
1 Asked on December 5, 2021 by stephen-horton
1 Asked on December 5, 2021 by kchou612
1 Asked on December 5, 2021 by tom-schreck
2 Asked on December 5, 2021 by andrea-dattero
1 Asked on December 5, 2021 by tamas-toth
4 Asked on December 5, 2021 by dragos-strugar
1 Asked on December 5, 2021 by user881667
firebase firebase authentication jestjs react testing library reactjs
2 Asked on December 5, 2021 by zenith2198
1 Asked on December 5, 2021 by ahmad-idrees
Get help from others!
Recent Answers
Recent Questions
© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP