如何从嵌套对象数组中提取对象示例

How to extract a sample of objects from array of nested objects

本文关键字:提取 取对象 数组 嵌套 对象      更新时间:2023-09-26

我正在用Javascript开发,我创建了folders包含对象的数组:

folders = [folder1, folder2, folder3...]

每个对象都有一些属性,其中一个是docs,它是一个对象数组:

docs = [doc1, doc2, doc3...]

。每个对象都是这样的:

doc1.title = 'foo'
doc1.desc = 'bar'
doc1.attr = {new: _.random(0, 1) > 0.5, read: _.random(0, 1) > 0.5}
...

我想创建一个函数,仅提取具有attr = {new: true, read: false}的文档。我尝试了一些下划线方法,例如 _.each_.sample_.find_.findWhere ,但我无法弄清楚如何从主数组中获取包含具有该attr属性的文档的示例。

知道吗?

使用下划线首先展平文件夹,然后使用从何处获取所需内容:

var result = _.where( _.flatten(folders), {new: true, read: false});

编辑以使用新结构:

var result = _.chain(folders)
    .pluck('docs')
    .flatten()
    .where({isNew: true, read: false})
    .value();

var folders = [
	{
		docs: [				
			{
				title: 'one',
				isNew: true,
				read: false
			},				{
				title: 'two',
				isNew: true,
				read: true
			}
		]
	},
	{
		docs: 
		[
			{
				title: 'three',
				isNew: false,
				read: false
			},				{
				title: 'four',
				isNew: true,
				read: false
			}
		]
	}
];
var result = _.chain(folders)
	.pluck('docs')
	.flatten()
	.where({isNew: true, read: false})
	.value();
document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore.js"></script>
<p>
  <pre id="result"></pre>
</p>

你试过这样的事情吗?

var result = [];
folders.forEach(function(docs) {
    result.concat( docs.filter(function(doc) {
        return doc.attr.new && !doc.attr.read;
    });
});

>像.find这样的方法在一层深度的数组上工作:

 var temp = [];
_.each(folders , function(docsArray){
    var result = _.where(docsArray ,  {new: true, read: false});
    if(result){
        temp.concat(result);
    }
});

您可以在不使用 下划线lodash 的情况下实现您想要的,只需利用内置的Array.mapArray.filter方法,下面是一个示例:

var myResult = folders.map(function(folder){
      return myCustomDocs = folder.filter(function(doc){
            return (doc.attr.new  && !doc.attr.read);
      });
});
console.log(myResult);

常规过滤器呢?

工作演示

(只需打开浏览器控制台并运行小提琴。

doc1.filter(o => o.attr.new && !o.attr.read)

您也可以简单地map() folders阵列。

const _folders = folders
  .map(doc => doc.filter(o => o.attr.new && !o.attr.read))

你会得到新的文件夹数组,其中包含只有new && !read个文档的数组。如果需要,您可以将其展平:

const flatFolders = [].concat.apply([], _folders)

我找到了一个可行的解决方案。这是我的代码:

var result = [];
folders.forEach(function(item) {
    result = result.concat(_.filter(item.docs, function(doc) {
        return doc.isNew === true && doc.read === false;
    }));
});

如果你有 Node.js 5+ 或使用 Babel,你可以做:

folders.reduce((res, arr) => res.concat(arr), [])      // flatten folders
       .filter(doc => doc.attr.new && !doc.attr.read); // remove all that don't return true