Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pluck specific keys from json array

I'm trying to pluck some key-values from json array and form another array, below is the sample json structure. I got one solution now. Just want to know what are the other methods to do the same.

Is there anyway to reject keys from array of objects.

Input

 var a = [{
   id: 1,
   name: "First Name",
   description: ""
 },{
   id: 2,
   name: "Second Name",
   description: ""
 }]

Output

 [{
   id: 1,
   name: "First Name"
 },{
   id: 2,
   name: "Second Name"
 }]

One Solution

var arr = [];
_.each(a,function(key,value){
   arr.push(_.pick(key,'name','id'));
});

UPDATED

Second Solution

 _.map(a, function(o) { return _.pick(o, 'name','id'); });
like image 854
tomalex Avatar asked May 21 '14 06:05

tomalex


2 Answers

Also we can use Vanilla JS including map, destructuring assignment and arrow function :

const a = [
  {
    id: 1,
    name: "First Name",
    description: ""
  },
  {
    id: 2,
    name: "Second Name",
    description: ""
  }
]


// we need only id and name
const result = a.map(({id, name})=>({id, name}))


// result:
[
  {
    id: 1,
    name: "First Name"
  },
  {
    id: 2,
    name: "Second Name"
  }
]
like image 179
Alizadeh118 Avatar answered Oct 14 '22 01:10

Alizadeh118


I would change one thing in your first solution, the parameter names in the _.each() callback. In fact you only need one parameter here, just like the second version:

var arr = [];
_.each(a,function(o){
   arr.push(_.pick(o,'name','id'));
});

But your second solution using _.map() is nicer - very clean and seems perfectly fine.

The first version is actually how _.map() works internally. Here's the source code for _.map():

// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
    var results = [];
    if (obj == null)
        return results;
    if (nativeMap && obj.map === nativeMap)
        return obj.map(iterator, context);
    each(obj, function(value, index, list) {
        results.push(iterator.call(context, value, index, list));
    });
    return results;
};

As you can see, it's basically the same code as your first version along with some extra stuff.

You asked about rejecting keys; you can do that with the _.omit() function, which is the opposite of _.pick(): you list the property names you want to omit, not the ones you want to copy. So with your test data, this would produce the same thing as the other versions:

_.map(a, function(o) { return _.omit(o, 'description'); });

The difference would be that if there were additional properties in the input data, this version would copy those properties into the output too. The version using _.pick() would only have id and name in the output.

My only additional suggestion would that if you're dealing with very large arrays it would be a little faster to do the equivalent of _.pick() yourself:

var result = _.map( a, function( o ) {
    return { name: o.name, id: o.id };
});

Or even faster to use your own loop:

var result = [];
for( var i = 0, n = a.length;  i < n;  ++i ) {
    var o = a[i];
    result[i] = { name: o.name, id: o.id };
}

But for a smallish array you may as well go with the simpler code.

like image 38
Michael Geary Avatar answered Oct 14 '22 01:10

Michael Geary