Stanley
Stanley

Reputation: 2816

javascript pattern matching object

Given a javascript object array eg.

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}]

is there a faster way of getting all the b values from each object which meet a specific criteria such as a = 1 to return something like

b_consolidated = [2,3]

instead of looping through every object in the array?

Upvotes: 0

Views: 195

Answers (5)

Jagdish Idhate
Jagdish Idhate

Reputation: 7742

More faster would be using .reduce

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}];

objArray.reduce(function(res,obj){
   if(obj.a===1)
     res.push(obj.b);
   return res;
},[]);

// [2,3]

Upvotes: 1

elpddev
elpddev

Reputation: 4494

In Ramda

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}]

R.pipe(
  R.filter(R.propEq('a', 1)),
  R.pluck('b')
)(objArray)

// [2, 3]
  • Filter returns the array values matched by the condition.
  • Pluck returns a new list by plucking the same named property off all objects in the list supplied.

Edit 1:

Example of using the mentioned reduce pattern in Ramda:

R.reduce((acc, x) => R.ifElse(
  R.propEq('a', 1), 
  (item) => R.pipe(R.prop('b'), R.append(R.__, acc))(item), 
  R.always(acc)
)(x), [])(objArray)

// [2, 3]

Upvotes: -1

Suren Srapyan
Suren Srapyan

Reputation: 68665

You can use Array#filter function to get the items of your criteria, then use Array#map to get only b property.

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}];

let values = objArray.filter(item => item.a === 1).map(item => item.b);

console.log(values);

Or you can do this in one loop

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}];
let values = [];

objArray.forEach(item => {

  if(item.a === 1) {
      values.push(item.b);
  }
  
});

console.log(values);

Upvotes: 4

Cerbrus
Cerbrus

Reputation: 72927

You only need to iterate over the array once, if you use reduce:

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}]

let result = objArray.reduce((arr, val) => {
  if(val.a === 1)
    arr.push(val.b);
  return arr;
}, []);

console.log(result);

This is as fast as it'll get, short of a manual for loop:

let objArray = [{a: 1, b: 2 , c:3},{a: 1, b:3, c:2},{a: 2, b:5, c:1}]

let result = [];

for(var i = 0 ; i < objArray.length; i++){
  if(objArray[i].a === 1)
    result.push(objArray[i].b);
}

console.log(result);

Here's a JSPerf to illustrate the difference.
A manual for loop is by far the fastest.

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386670

You could use Array#reduce in a single loop.

let array = [{ a: 1, b: 2, c: 3}, { a: 1, b: 3, c: 2 }, { a: 2, b: 5, c: 1 }],
    result = array.reduce((r, o) => o.a === 1 ? r.concat(o.b) : r, []);

console.log(result);

Fastest version with for loop.

let array = [{ a: 1, b: 2, c: 3}, { a: 1, b: 3, c: 2 }, { a: 2, b: 5, c: 1 }],
    i, l,
    result = [];

for (i = 0, l = array.length; i < l; i++) {
    if (array[i].a === 1) {
        result.push(array[i].b);
    }
}

console.log(result);

Upvotes: 3

Related Questions