简体   繁体   English

从对象数组中提取对象

[英]Extract object from object array

I need to split an object array into two variables. 我需要将一个对象数组拆分为两个变量。 The first variable ( main ) should get the object with a title . 第一个变量( main )应该获得带有title的对象。 The second one ( content ) should get all other objects. 第二个( content )应该获得所有其他对象。

Sample data 样本数据

[
  { _id: '1', title: 'Main' },
  { _id: '2', foo: 'bar' },
  { _id: '2', foo: 'bar' }
]

I did it with find() / filter() commands, but is it really necessary to find twice? 我用find() / filter()命令做到了,但是真的有必要找两次吗?

const main = data.find(doc => doc.title)
const content = data.filter(doc => !doc.title)

Is it possible to extract the main object instead of finding it? 是否有可能提取主要对象而不是找到它?

You could take a single loop approach and an object for same named arrays with a check if the property exist with in operator . 您可以采用单循环方法和相同命名数组的对象,并检查属性是否存在in运算符中

 var data = [{ _id: '1', title: 'Main' }, { _id: '2', foo: 'bar' }, { _id: '2', foo: 'bar' }], main = [], content = [], temp = { main, content }; data.forEach(doc => temp['title' in doc ? 'main' : 'content'].push(doc)); console.log(main); console.log(content); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

With just one object with title, you could assign the object directly and collec the other objects in an array. 只有一个带标题的对象,您可以直接分配对象并收集数组中的其他对象。

 var data = [{ _id: '1', title: 'Main' }, { _id: '2', foo: 'bar' }, { _id: '2', foo: 'bar' }], main, content = []; data.forEach(doc => 'title' in doc ? main = doc : content.push(doc) ); console.log(main); console.log(content); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

const content = data.find(doc => !doc.title)

This doesn't work, because find returns one object only (the first found), not all the objects that don't match the condition. 这不起作用,因为find只返回一个对象(第一个找到),而不是所有与条件不匹配的对象。 You'll have to use a filter for that 你必须使用过滤器

const content = data.filter(doc => !doc.title)

So yes, you'll have to iterate twice, one time to find the matching object, and a second time to build an array excluding the matching object. 所以是的,你必须迭代两次,一次找到匹配的对象,第二次构建一个排除匹配对象的数组。

var docs = [
  { _id: '1', title: 'Main' },
  { _id: '2', foo: 'bar' },
  { _id: '2', foo: 'bar' }
];

var doc = [],main = [];

for(_doc in docs){
    if(typeof docs[_doc].title != 'undefined') {
        doc.push(docs[_doc]);
        continue;
  }

  main.push(docs[_doc]);
}

Working fiddle: https://jsfiddle.net/andreitodorut/fcLkata6/ 工作小提琴: https//jsfiddle.net/andreitodorut/fcLkata6/

I would do this a bit differently. 我会这样做有点不同。 The notion of partitioning a list by a predicate is worth extracting. 通过谓词对列表进行分区的概念值得提取。 So I might do this: 所以我可能这样做:

 const docs = [{_id: '1', title: 'Main'},{_id: '2', foo: 'bar'},{_id: '2', foo: 'bar'}] const partition = pred => data => data.reduce( ([matches, mismatches], item) => pred(item) ? [matches.concat(item), mismatches] : [matches, mismatches.concat(item)], [[], []] ) const withTitle = partition(doc => 'title' in doc) console.log(withTitle(docs)) 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Of course it's quite possible that withTitle should be inlined, if it's not being reused. 当然,如果没有重复使用withTitle ,那么它很可能是内联的。 It's also possible that the currying I put in, my usual default, is not necessary for you, and it should read (pred, data) => data.reduce(...) 也可能我输入的currying,我通常的默认值,对你来说不是必需的,它应该读取(pred, data) => data.reduce(...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM