Find object and parent object in repeatedly nested array

问题: How to find an object and parent object in repeatedly nested array of unknown size? Using lodash or native javascript. Array might be something like this: va...

问题:

How to find an object and parent object in repeatedly nested array of unknown size? Using lodash or native javascript.

Array might be something like this:

var modules = [{
    name: 'Module1',
    submodules: [{
        name: 'Submodule1',
        id: 1,
        submodules: [{
          name: 'Submodule11',
          id: 1,
          submodules: []
        }, {
          name: 'Submodule12',
          id: 2,
          submodules: [{
            name: 'Submodule121',
            id: 1,
            submodules: []
          }, {
            name: 'Submodule122',
            id: 2,
            submodules: []
          }]
        }]
      },
      {
        name: 'Submodule2',
        id: 2,
        submodules: []
      }
    ]
  },
  {
    name: 'Module2',
    submodules: [{
      name: 'Submodule1',
      id: 3,
      submodules: []
    }, {
      name: 'Submodule2',
      id: 4,
      submodules: []
    }]
  }
];

And let's say all the 'name' properties in array are unique.

And I want to find:

name: 'Submodule122'

I was using this function for finding parent object but it works only on first level of array:

_.find(this.modules , function(item) {
            return _.some(item.submodules, { name: 'Submodule122'});

And this to find actual object, but it also works only on first level of array:

_(this.modules)
            .thru(function (coll) {
                return _.union(coll, _.map(coll, 'submodules'));
            })
            .flatten()
            .find({ name: 'Submodule122'})

回答1:

You could take an iterative and recursive approach by keeping the actual object as parent.

function find(name, array, parent) {
    var result;
    array.some(object =>
        object.name === name && (result = { object, parent }) || 
        (result = find(name, object.submodules, object))
    );
    return result;
}

var modules = [{ name: 'Module1', submodules: [{ name: 'Submodule1', id: 1, submodules: [{ name: 'Submodule11', id: 1, submodules: [] }, { name: 'Submodule12', id: 2, submodules: [{ name: 'Submodule121', id: 1, submodules: [] }, { name: 'Submodule122', id: 2, submodules: [] }] }, { name: 'Submodule2', id: 2, submodules: [] }] }, { name: 'Module2', submodules: [{ name: 'Submodule1', id: 3, submodules: [] }, { name: 'Submodule2', id: 4, submodules: [] }] }] }];

console.log(find('Submodule122', modules));
.as-console-wrapper { max-height: 100% !important; top: 0; }


回答2:

var modules = [{
    name: 'Module1',
    submodules: [{
        name: 'Submodule1',
        id: 1,
        submodules: [{
          name: 'Submodule11',
          id: 1,
          submodules: []
        }, {
          name: 'Submodule12',
          id: 2,
          submodules: [{
            name: 'Submodule121',
            id: 1,
            submodules: []
          }, {
            name: 'Submodule122',
            id: 2,
            submodules: []
          }]
        }]
      },
      {
        name: 'Submodule2',
        id: 2,
        submodules: []
      }
    ]
  },
  {
    name: 'Module2',
    submodules: [{
      name: 'Submodule1',
      id: 3,
      submodules: []
    }, {
      name: 'Submodule2',
      id: 4,
      submodules: []
    }]
  }
];

var findByName = (name, module, parent, item) => {
  parent.push(...module.filter(x => Array.isArray(x.submodules) && x.submodules.some(y => y.name == name)));
  item.push(...module.filter(y => y.name == name));

  module.forEach(x => {
    if (Array.isArray(x.submodules) && x.submodules.length > 0) {
      findByName(name, x.submodules, parent, item);
    }
  });

}

var parents = [], items = [];
findByName('Submodule12', modules, parents, items);
console.log(parents);
console.log(items);

  • 发表于 2018-07-10 10:54
  • 阅读 ( 240 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除