如何从嵌套对象数组中提取对象样本

时间:2016-03-10 14:10:45

标签: javascript arrays underscore.js extract javascript-objects

我在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属性的文档。

有什么想法吗?

7 个答案:

答案 0 :(得分:1)

首先使用下划线flatten文件夹,然后使用where获取您想要的内容:

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>

答案 1 :(得分:0)

常规过滤器怎么样?

Working Demo

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

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)

答案 2 :(得分:0)

你尝试过这样的事吗?

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

答案 3 :(得分:0)

像[{1}}这样的下划线方法适用于深度为一级的数组:

.find

答案 4 :(得分:0)

你可以使用下划线 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);

答案 5 :(得分:0)

如果你有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

答案 6 :(得分:0)

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

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