GPiter
GPiter

Reputation: 809

How does one, within a nested object structure, recursively collect different types of object ids?

I have this data :

{
   "id": 26578,
   "label": "CatA",
   "value": 26578,
   "children": [
     {
        "id": 26579,
        "label": "CatB",
        "value": 26579,
        "children": [
           {
              "id": 26580,
              "label": "CatC",
              "value": 26580,
              "children": null
           },
           {
              "id": 26581,
              "label": "CatD",
              "value": 26581,
              "children": null
           }
        ]
     }
   ]
},

I know the value 26578, I called chosenSubcategoryId

I want to get 2 arrays :

expanded = [26578, 26579]
checked  = [26580, 26581]

I try like this :

const recursion = (item, chosenSubcategoryId) => {
        if (Array.isArray(item)) {
            item.map(item => {
                if (item.id === chosenSubcategoryId) {
                    recursion(item.children, item.id);
                }
            })
        }
}
recursion(this.props.chosenCategory.children, this.props.chosenSubcategory.id);

But not working properly. Please help me ! Thx in advance.

Upvotes: 0

Views: 386

Answers (3)

Peter Seliger
Peter Seliger

Reputation: 13377

Note: A valid check for whether an object is considered expanded or checked not only depends on the existence of such an object's children array but also on this array not being an empty one.

function mapBranchAndLeafIds(obj, map = { branchIds: [], leafIds: [] }) {
  const { children } = obj;
  if (Array.isArray(children) && (children.length >= 1)) {

    // collect "expanded" object id.
    map.branchIds.push(obj.id);

    // for each child object step into the recursion.
    map = children.reduce((collector, childObj) =>
      mapBranchAndLeafIds(childObj, collector),
      map
    );
  } else {
    // collect "checked" object id.
    map.leafIds.push(obj.id);
  }
  return map;
}

const sampleObject = {
  "id": 26578,
  "label": "CatA",
  "value": 26578,
  "children": [{
    "id": 26579,
    "label": "CatB",
    "value": 26579,
    "children": [{
      "id": 26580,
      "label": "CatC",
      "value": 26580,
      "children": null,
    }, {
      "id": 26581,
      "label": "CatD",
      "value": 26581,
      "children": null,
    }],
  }],
};
const mappedIds = mapBranchAndLeafIds(sampleObject);
const {

  branchIds: expanded ,
  leafIds: checked,

} = mappedIds;

console.log('mappedIds :', mappedIds);

console.log('expanded :', expanded);
console.log('checked :', checked);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Upvotes: 1

Md Sabbir Alam
Md Sabbir Alam

Reputation: 5054

You can do the following,

objP = {
   "id": 26578,
   "label": "CatA",
   "value": 26578,
   "children": [
     {
        "id": 26579,
        "label": "CatB",
        "value": 26579,
        "children": [
           {
              "id": 26580,
              "label": "CatC",
              "value": 26580,
              "children": null
           },
           {
              "id": 26581,
              "label": "CatD",
              "value": 26581,
              "children": null
           }
        ]
     }
   ]
};

expanded = [];
checked = [];

getChildId = (obj) => {
  if(obj.children) {
    expanded.push(obj.id);
    obj.children.forEach(item => {
      getChildId(item);
    })
  } else {
    checked.push(obj.id);
  }
  return;
}

getChildId(objP);
console.log(expanded);
console.log(checked);

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 191986

After you've found the subcategory this condition item.id === chosenSubcategoryId would always be false.

To get the ids of the subcategory items, use an internal recursion. I've used Array.forEach() to iterate the items, add the ids to the respective arrays in the result (res), and iterate the children recursively.

const fn = o => {
  const res = { expanded: [], checked: []};
  
  const recursion = o => {
    if(o.children === null) {
      res.checked.push(o.id);
    } else {
      res.expanded.push(o.id);
      
      o.children.forEach(recursion);
    }
  }
  
  recursion(o);
  
  return res;
};

const obj = {"id":26578,"label":"CatA","value":26578,"children":[{"id":26579,"label":"CatB","value":26579,"children":[{"id":26580,"label":"CatC","value":26580,"children":null},{"id":26581,"label":"CatD","value":26581,"children":null}]}]};

const result = fn(obj);

console.log(result);

Upvotes: 1

Related Questions