在嵌套数组中通过匹配 属性 查找对象

Find object by match property in nested array

当我的条件涉及嵌套数组时,我没有找到 find 对象的方法。

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

这行不通,因为 submodules 是数组,不是对象。是否有任何 shorthand 可以使这项工作?我试图避免手动迭代数组。

_.where(modules, {submodules:{id:3}});

我认为你最好的机会是使用函数来获取模块。

_.select(modules, function (module) {
  return _.any(module.submodules, function (submodule) {
    return _.where(submodule, {id:3});
  });
});

试试这个来获取子模块

.where(.pluck(modules, "submodules"), {submodules:{id:3}});

这是我想出的:

_.find(modules, _.flow(
    _.property('submodules'),
    _.partialRight(_.some, { id: 2 })
));
// → { name: 'Module1', ... }

使用 flow(), you can construct a callback function that does what you need. When call, the data flows through each function. The first thing you want is the submodules property, and you can get that using the property() 函数。

然后子模块数组被送入 some(),如果它包含您要查找的子模块,则 returns 为真,在本例中,ID 2.

如果您要查找多个模块,而不仅仅是找到的第一个模块,请将 find() 替换为 filter()

Lodash 允许您像这样过滤嵌套数据(包括数组):

_.filter(modules, { submodules: [ { id: 2 } ]});

我对此进行了调查,我认为最好的选择是使用 Deepdash。它是深度过滤、查找等方法的集合。

当然,单独使用 lodash 是可能的,但使用 Deepdash 会更容易。

我尝试将之前的答案转换为最新的 Lodash 版本,但没有成功。 Lodash 的 v4 中弃用了所有方法。可能的替换:select = map 或 filter,any = some,where = filter)

findDeep returns 一个包含所找到项目的一些信息的对象(只是一些值,有关详细信息,请参阅 docs):

  • value是找到的对象
  • key 这是嵌套数组中的索引
  • parent 值的父级

因此 findDeep 的代码如下所示:

const modules = [{
  name: 'Module1',
  submodules: [{
    name: 'Submodule1',
    id: 1
  }, {
    name: 'Submodule2',
    id: 2
  }]
}, {
  name: 'Module2',
  submodules: [{
    name: 'Submodule1',
    id: 3
  }, {
    name: 'Submodule2',
    id: 4
  }]
}];

const getModule = (modules, id) =>
  _.findDeep(modules, module => module.id === id, {
    childrenPath: "submodules"
  });


const resultEl = document.getElementById("result");
const foundModule = getModule(modules, 3).value;

resultEl.innerText = JSON.stringify(foundModule, null, 2);
<script src="https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script>
  deepdash(_);
</script>

<h2>Example to get module with id = 3</h2>
<pre id="result"></pre>