Построить список предков из вложенного массива - PullRequest
1 голос
/ 16 октября 2019

Вложенный массив выглядит так:

var arr = [{
  id: 2,
  name: 'a',
  children: []
}, {
  id: 5,
  name: 'b',
  children: [{ 
    id: 14,
    name: 'b2'
  }]

}, {
  id: 15,
  name: 'd',
  children: []
}];

Как я могу составить список элементов-предков из любого данного элемента?

Например, если у данного элемента есть id: 14, список должен возвращатьсятолько родитель:

[{
  id: 5,
  name: 'b',
  children: [...]
}] 

Я пытаюсь воспроизвести навигацию "крошка"

Ответы [ 4 ]

2 голосов
/ 16 октября 2019

Вы можете передать объект, который является родительским, и выполнить рекурсивный поиск для требуемого id.

function getParent(object, id) {
    var result;
    (object.children || []).some(o => result = o.id === id ? object : getParent(o, id));
    return result;
}

var array = [{ id: 2, name: 'a', children: [] }, { id: 5, name: 'b', children: [{  id: 14, name: 'b2' }] }, { id: 15, name: 'd', children: [] }];

console.log(getParent({ children: array }, 14));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Если вы хотите передать массив, вы можете использовать вложенный подход с рекурсивной функцией.

function getParent(children, id) {

    function iter(object) {
        var result;
        (object.children || []).some(o => result = o.id === id ? object : iter(o));
        return result;
    }

    return iter({ children });
}

var array = [{ id: 2, name: 'a', children: [] }, { id: 5, name: 'b', children: [{  id: 14, name: 'b2' }] }, { id: 15, name: 'd', children: [] }];

console.log(getParent(array, 14));
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 16 октября 2019

Алгоритм поиска в глубину - получить родительский узел:

function getParentNodeByKey(obj, targetId, paramKey) {
    if (obj.children) {
        if (obj.children.some(ch => ch[paramKey] === targetId))
            return obj;
        else {
            for (let item of obj.children) {
                let check = this.getParentNodeByKey(item, targetId, paramKey)
                if (check) {
                    return check;
                }
            }
        }
    }
    return null
}

и код для проверки:

var arr = [{
    id: 2,
    name: 'a',
    children: []
  }, {
    id: 5,
    name: 'b',
    children: [{
      id: 14,
      name: 'b2'
    }]

  }, {
    id: 15,
    name: 'd',
    children: []
}];

let parentElement;
const valueToFind = 14;
const desiredkey = 'id';
for (let i = 0; i < arr.length; i++) {
    parentElement = getParentNodeByKey(arr[i], valueToFind, desiredkey);
    if(parentElement)
        break;
}

console.log(`The parent element is:`, parentElement);
1 голос
/ 16 октября 2019

Вы можете попробовать таким образом,

     var arr = [{
          id: 2,
          name: 'a',
          children: []
        }, {
          id: 5,
          name: 'b',
          children: [{ 
            id: 14,
            name: 'b2'
          }]

        }, {
          id: 15,
          name: 'd',
          children: []
        }];


    function getAncestor(obj,id,ancestor){
     if(obj.id===id){
        console.log(ancestor);
     }
     else
        if(obj&& obj.children && obj.children.length)
            obj.children.forEach(item=>this.getAncestor(item,id,obj));
    }

arr.forEach(o=>getAncestor(o,14,{}));
1 голос
/ 16 октября 2019

Если мы можем предположить, что существуют только два уровня (родители и дети, а не дети детей), то следующая функция findAncestor() делает то, что вам нужно. Он перебирает все родительские элементы и проверяет, есть ли у них дочерний элемент с соответствующим идентификатором.

function findAncestor(id) {
  for (let i = 0; i < arr.length; i++) {
    let obj = arr[i];
    if (obj.hasOwnProperty('children')) {
      if (obj.children.length > 0) {
        for (let j = 0; j < obj.children.length; j++) {
          if (obj.children[j].id === id) {
            return obj;
          }
        }
      }
    }
  }

  return null;
}

console.info(findAncestor(14));

Если вам нужно обработать случай, когда дочерний элемент с одинаковым идентификатором может встречаться у нескольких родителей, вы должны использоватьмассив результатов и добавьте в него все найденные результаты, прежде чем возвращать его в конце.

...