1

I am getting object like this from the Server,

var data = {
  test1: {
    documents: []
  },
  test2: {
    documents: [{
      vId: 'sdfas23',
      TypeId: '81',
      isDeleted: false
    }],
    answer: true
  },
  test3: {
    documents: [{
      vId: 'H1mJinyI',
      TypeId: '82',
      isDeleted: false
    }],
    answer: true
  }
}

i want to filter the typeId from the object, The Result i am Expecting is

[81,82]

can anybody help on this.

2
  • 1
    How far did you get when you attempted to write the relevant code? Where did you get stuck? What went wrong? Commented Jun 28, 2016 at 10:31
  • I once encountered a similar use-case and i used lodash map(). Read the cocs here: lodash.com/docs#map Commented Jun 28, 2016 at 10:33

9 Answers 9

3

In case you have only one or zero objects in documents like in your example you can use reduce() with Object.keys()

var data = {"test1":{"documents":[]},"test2":{"documents":[{"vId":"sdfas23","TypeId":"81","isDeleted":false}],"answer":true},"test3":{"documents":[{"vId":"H1mJinyI","TypeId":"82","isDeleted":false}],"answer":true}}

var result = Object.keys(data).reduce(function(a, e) {
  if (data[e].documents[0]) a.push(data[e].documents[0].TypeId);
  return a;
}, [])

console.log(result)

For multiple objects in documents array you can add forEach loop to previous code so you get this (there are two objects in test3.documents)

var data = {"test1":{"documents":[]},"test2":{"documents":[{"vId":"sdfas23","TypeId":"81","isDeleted":false}],"answer":true},"test3":{"documents":[{"vId":"H1mJinyI","TypeId":"82","isDeleted":false},{"vId":"Random","TypeId":"100","isDeleted":false}],"answer":true}}

var result = Object.keys(data).reduce(function(a, e) {
  if (data[e].documents.length) data[e].documents.forEach(function(p) {
    a.push(p.TypeId);
  });
  return a;
}, [])

console.log(result);

Sign up to request clarification or add additional context in comments.

3 Comments

@RIYAJ KHAN Thanks.
Why have you added check for length for forEach?
@Rajesh length check is added to eliminate elements with documents = [] which is true for data.test1.documents
2

You could do this with just a single line of code:

_.map(_.flatten(_.map(_.values(data), 'documents')), 'TypeId');

This will produce:

["81", "82"]

Comments

0

This gives you the expected result, though not sure will you be happy with it

var data=  { 
    test1: { documents: [] },
    test2: { documents: [{ vId: 'sdfas23',
          TypeId: '81',
          isDeleted: false }], answer: true },
    test3:
     { documents:
        [{ vId: 'H1mJinyI',
          TypeId: '82',
          isDeleted: false }],
       answer: true } 
} 

function getIds(array) {
    var ret = [];
    for (key in data) {
        for (key2 in data[key].documents) {
            ret.push(data[key].documents[key2].TypeId)
         }
    }
    return ret
}

console.log(getIds(data));

Comments

0

You can do something like this:

  1. Get access to every object in a way, you can use same expression for it. for...in will help you get keys of an object and you can use data[key] to get object.
  2. Now once we have object, we know where to look i.e. obj.documents. Now documents is an array and we need to get TypeId in every object in it. For this, you can have an array and manually push value in it or you can use Array.map.
  3. Now if you use .map, it will return an array for every object. So you will have to use array.concat to append it to same function. But if you use .push, then skip this step.

For..in + .map + .concat

var data={test1:{documents:[]},test2:{documents:[{vId:"sdfas23",TypeId:"81",isDeleted:!1}],answer:!0},test3:{documents:[{vId:"H1mJinyI",TypeId:"82",isDeleted:!1}],answer:!0}};

var r = [];
for(var k in data){
  r = r.concat(data[k].documents.map(function(o){return o.TypeId}));
}

console.log(r)

3 Comments

@Downvoter, please comment what is missing in the answer.
Am not the downvoter, i know you have a good solution, but please include some explanations so beginners and others will benefit from this good answer.
@hamism I have updated the answer. Hope it explains properly.
0

If property "documents" always have only one object, just use _.compact(_.map(data, 'documents[0].TypeId'));

If property "documents" have many objects, use _.flatten(_.map(data, (item) => _.map(item.documents, 'TypeId')));

Example - https://jsfiddle.net/qvkctvho/1/

Comments

0

Here is another simplified version of the previous answers(no reduce and fancy stuff only map ) :

var data=  { test1: { documents: [] },
             test2: { documents: [{ vId: 'sdfas23', TypeId: '81', isDeleted: false },{ vId: 'sdfas23', TypeId: '85', isDeleted: false }], answer: true },
             test3: { documents: [{ vId: 'H1mJinyI', TypeId: '82', isDeleted: false }], answer: true } 
};

var getTypeIds = function(data){
    var ids = [];
   // get object keys in this case : test1,test2,test3
    Object.keys(data).map(function(key){        
        // loop through each document attribute and extract TypeId attributes
        data[key].documents.map(function(item){                                                
                                    ids.push(item.TypeId);                                    
                                });


    })
    return ids;   
}

console.log(getTypeIds(data)); // [ '81', '85', '82' ]

Comments

0

Try this

Object.getOwnPropertyNames(data).map(function(val, key) {    
    return data[val].documents[0] ? data[val].documents[0].TypeId : '';    
})

Comments

0

You can use _.map function of lodash to get the result you want. Here is the sample code -

var result = _.map(data, function(v,i){
    if(_.isArray(v.documents)) {
        return v.documents[0].TypeId
    }

    return ''
}

Comments

0

The easiest way to solve this in lodash is by using flatMap() to get a flattened array of documents and map() to get all TypeId.

var result = _(data)
.flatMap('documents')
.map('TypeId')
.value();

var data = {
  test1: {
    documents: []
  },
  test2: {
    documents: [{
      vId: 'sdfas23',
      TypeId: '81',
      isDeleted: false
    }],
    answer: true
  },
  test3: {
    documents: [{
      vId: 'H1mJinyI',
      TypeId: '82',
      isDeleted: false
    }],
    answer: true
  }
};

var result = _(data)
.flatMap('documents')
.map('TypeId')
.value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>

A plain JS solution with ES6 should be something like this:

var result = Object.keys(data) // get keys as reference when mapping
.map(v => data[v].documents || []) // get all documents
.reduce((x, y) => x.concat(y)) // flatten
.map(v => v.TypeId); // get TypeId

var data = {
  test1: {
    documents: []
  },
  test2: {
    documents: [{
      vId: 'sdfas23',
      TypeId: '81',
      isDeleted: false
    }],
    answer: true
  },
  test3: {
    documents: [{
      vId: 'H1mJinyI',
      TypeId: '82',
      isDeleted: false
    }],
    answer: true
  }
};

var result = Object.keys(data)
.map(v => data[v].documents || [])
.reduce((x, y) => x.concat(y))
.map(v => v.TypeId);

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.