Extract an object from an array of objects

I need to split an array of objects into two variables. The first variable ( main) should get the object c title. The second ( content) should get all other objects.

Data examples

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

I did this with the find()/ commands filter(), but do I really need to find twice?

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

Is it possible to extract the main object instead of searching for it?

+4
source share
4 answers

You can use a single loop approach and an object for the same arrays with a check to see if a property exists with inoperator .

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; }
Run codeHide result

With just one object with a header, you can directly assign an object and collect 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; }
Run codeHide result
+2
const content = data.find(doc => !doc.title)

, find ( ), , .

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

, , , , , .

0
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/

0
source

I would do it a little differently. The concept of splitting a list into a predicate is worth extracting. Therefore, I can 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; }
Run codeHide result

Of course, it is entirely possible that it withTitleshould be built in if it is not reused. It is also possible that I use currying, my usual default, you do not need, and it should read(pred, data) => data.reduce(...)

0
source

Source: https://habr.com/ru/post/1692586/


All Articles