Kamil Staszewski
Kamil Staszewski

Reputation: 346

Filtering array with objects inside an object

I have a problem with filtering an array with nested objects.

[{
    "firstName": "Kevin",
    "lastName": "Smith",
    "expenses": {
      "drink1": 25,
      "drink2": 20
    }
  },
  {
    "firstName": "John",
    "lastName": "Rambo",
    "expenses": {
      "coffe": 10,
      "cake": 20
    }
  }
]

I want to get the objects where the sum of all expenses is > 35. How to get inside expenses? Or maybe filter is not a proper way here.

Upvotes: 8

Views: 2981

Answers (5)

DontFeedTheHypeMachine
DontFeedTheHypeMachine

Reputation: 310

I'm assuming that you need to keep you array of users the way it is, but with the expenses filtered.

(I assumed wrong as pointed in the comment, keeping this answer just in case someone sees any value on it)

Probably this can be optmized or simplified, but here it goes:

arr.reduce((acc, user) => [...acc,
  Object.keys(user).reduce((userResult, key) => {
    if (key === 'expenses') {
      return {
         ...userResult,
        expenses: Object.entries(elem.expenses)
          .filter(([product, value]) => value > 35)
          // now "reversing" the object.entries
          .reduce((acc, [product, value]) => ({ [product]: value }), {})
      }
    }
    return {
      ...userResult,
      [key]: elem[key]
    }
  }, user) // starts with the user
], []) //starts with empty array

Upvotes: 1

Velimir Tchatchevsky
Velimir Tchatchevsky

Reputation: 2825

A possible solution might be:

arr.filter(function(v){ for(expense in v.expenses){ if(v.expenses[expense] > 10){ return true; }else{ return false; } } })

Upvotes: -3

Tornike Shavishvili
Tornike Shavishvili

Reputation: 1354

You can access object at index i inside array arr with expression arr[i] What you need to do is to loop over your array. Inside your loop you access each object with expression i have mentioned: arr[i] and then on this object you can access expenses following way arr[i].expenses after this - if i am understanding correctly you sum contents of your arr[i].expenses object and select those objects which satisfy your condition. Please, See code below:

var expensesAbove35Arr = [];

var yourArray = [
        {
            "firstName": "Kevin",
            "lastName": "Smith",
            "expenses": {
                          "drink1": 26,
                           "drink2": 20
                        }
        },
        {
            "firstName": "John",
            "lastName": "Rambo",
            "expenses": {
                          "coffe": 10,
                           "cake": 20
                        }
        }
];

for(var i=0; i<yourArray.length; i++){
    if(yourArray[i].expenses.coffe + yourArray[i].expenses.cake > 35 ){
        expensesAbove35Arr.push(yourArray[i]);
    }
}

You have got your result inside array expensesAbove35Arr

Upvotes: 0

Alfredo A.
Alfredo A.

Reputation: 1787

You can try something like this

var data = [{
    "firstName": "Kevin",
    "lastName": "Smith",
    "expenses": {
      "drink1": 25,
      "drink2": 20
    }
  },
  {
    "firstName": "John",
    "lastName": "Rambo",
    "expenses": {
      "coffe": 10,
      "cake": 20
    }
  }
]

var filtered = data.filter(c => Object.keys(c.expenses)
                                .reduce(function(p, e) {
                                     return p + c.expenses[e]
                                       }, 0) >= 35
                           );

console.log(filtered);

Upvotes: 0

sjahan
sjahan

Reputation: 5960

Just filter it, with a condition using reduce to sum the expenses! Pretty straight forward :)

const input = [{
    "firstName": "Kevin",
    "lastName": "Smith",
    "expenses": {
      "drink1": 26,
      "drink2": 20
    }
  },
  {
    "firstName": "John",
    "lastName": "Rambo",
    "expenses": {
      "coffe": 10,
      "cake": 20
    }
  }
];

const output = input.filter(user => Object.values(user.expenses).reduce((acc, expense) => acc + expense) > 45);
console.log(output);

Upvotes: 10

Related Questions