Как в структуре вложенных объектов рекурсивно собирать разные типы идентификаторов объектов?

#javascript #arrays #algorithm #recursion

#javascript #массивы #алгоритм #рекурсия

Вопрос:

У меня есть эти данные :

 {
   "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
           }
        ]
     }
   ]
},
 

Я знаю значение 26578 , я вызвал chosenSubcategoryId

Я хочу получить 2 массива :

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

Я пытаюсь так :

 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);
 

Но не работает должным образом. Пожалуйста, помогите мне! Заранее спасибо.

Ответ №1:

После того, как вы нашли подкатегорию, это условие item.id === chosenSubcategoryId будет выполняться всегда false .

Чтобы получить идентификаторы элементов подкатегории, используйте внутреннюю рекурсию. Я использовал Array.forEach() итерацию элементов, добавление идентификаторов в соответствующие массивы в result ( res ) и рекурсивную итерацию дочерних элементов.

 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); 

Ответ №2:

Вы можете сделать следующее,

 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); 

Ответ №3:

Примечание: допустимая проверка того, считается ли объект расширенным или проверенным, зависит не только от существования массива такого объекта children , но и от того, что этот массив не является пустым.

 function mapBranchAndLeafIds(obj, map = { branchIds: [], leafIds: [] }) {
  const { children } = obj;
  if (Array.isArray(children) amp;amp; (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; }