Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

98
Views
Push object into array in recursion

I have two arrays: first arr - has multiple level structure.
second arr - linear array with objects.

In my update function I iterate throw my first array childrens and if condition true, I push objects into attributes.

In production - I have arr2.length - 150000 objects and arr1.length - multiple deep levels.

How I can optimize my function to loop more quickly with a big data? Now, I wait about 5 minutes on iteration.

var arr1 = [{
    "item_id": 2,
    "item_name": "test",
    "children": [{
        "item_id": 39646,
        "item_name": "test1",
        "children": [{
            "item_id": 35648,
            "item_name": "test2",
            "children": [{
                "item_id": 35771,
                "item_name": "test3",
                "children": [],
                "attributes": []
            }],
        }]
    }]
}]


var arr2 = [
    {
        "item_id": 35771,
        "attr_value": "test",
    }, {
        "item_id": 35771,
        "attr_value": "test1",
    }
]


const update = (array, id, object) => array.forEach(o => o.item_id === id ?
    o.attributes.push(object) : update(o.children, id, object)
);

for (let item of arr2) {
   update(arr1, item.item_id, item);
}

console.log(arr1)

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

We can walk the tree once, after converting your second array into this format:

{
  35771: ['test', 'test1']
  // ...
}

and for each node of the tree just adding the attributes from this list if they exist. Here's an implementation:

const updateForest = (atts) => (forest) =>
  forest .map (({item_id, children = [], ...rest}) => ({
    item_id,
    ...rest,
    children: updateForest (atts) (children),
    ...(atts [item_id] ? {attributes: atts [item_id]} : {})
  }))

const addAttributes = (forest, atts) => 
  updateForest (atts .reduce (
    (a, {item_id, attr_value}) => ((a [item_id] = a [item_id] || []), (a [item_id] .push (attr_value)), a), 
    {}
  )) (forest)

const arr1 = [{item_id: 2, item_name: "test", children: [{item_id: 39646, item_name: "test1", children: [{item_id: 35648, item_name: "test2", children: [{item_id: 35771, item_name: "test3", children: [], attributes: []}]}]}]}]
const arr2 = [{item_id: 35771, attr_value: "test"}, {item_id: 35771, attr_value: "test1"}]


console .log (addAttributes (arr1, arr2))
.as-console-wrapper {max-height: 100% !important; top: 0}

updateForest receives the attributes reformatted as described and returns a function which takes your forest structure (it's not a tree, because it's not necessarily singly-rooted) and visits its nodes, adding attributes if they exist, recurring on the list of children.

Our public function is addAttributes. This uses reduce to do that format conversion on your attributes, passing it and then the forest to updateForest.

It's important to not that this does not mutate your original structures, but creates new ones. I find this an important goal when coding. But if your data is so large that we can't fit two copies in memory, then we'd have to skip this approach.

about 4 years ago · Juan Pablo Isaza Report

0

One way would be to create a map that tells you exactly where to find the item in arr1.
Something like this:

const mappedArr1 = {
    2: {}, // Reference to item 2
    39646: {}, // Reference to item 39646
    35648: {}, // Reference to item 35648
    35771: {}, // Reference to item 35771
}

And when you update just do:

const item = mappedArr1[id];
item.attributes.push(object);

To create the map maybe use something like this:

const map = array => {
  const data = {};
  const doMap = array => array.forEach(i => {
    data[i.item_id] = i;
    if (i.children && i.children.length > 0) {
      doMap(i.children);
    }
  });
  doMap(array);
    return data;
}

const mappeArr1 = map(arr1);

Here is the full code:

var arr1 = [{
    "item_id": 2,
    "item_name": "test",
    "children": [{
        "item_id": 39646,
        "item_name": "test1",
        "children": [{
            "item_id": 35648,
            "item_name": "test2",
            "children": [{
                "item_id": 35771,
                "item_name": "test3",
                "children": [],
                "attributes": []
            }],
        }]
    }]
}]


var arr2 = [
    {
        "item_id": 35771,
        "attr_value": "test",
    }, {
        "item_id": 35771,
        "attr_value": "test1",
    }
]

const map = array => {
  const data = {};
  const doMap = array => array.forEach(i => {
    data[i.item_id] = i;
    if (i.children && i.children.length > 0) {
      doMap(i.children);
    }
  });
  doMap(array);
  return data;
}

const mappedArr1 = map(arr1);

for (let i of arr2) {
   const item = mappedArr1[i.item_id];
   item.attributes.push(i.attr_value);
}

console.log(arr1)

Use JSBench to test the performance of multiple implementations, you will need a bigger data sample: https://jsbench.me

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!