admin管理员组

文章数量:1278722

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.

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.

Share Improve this question edited Nov 7, 2018 at 18:51 Felix Kling 817k181 gold badges1.1k silver badges1.2k bronze badges asked Nov 7, 2018 at 18:42 Kamil StaszewskiKamil Staszewski 3461 gold badge8 silver badges21 bronze badges 8
  • This should give you an idea: Sum all properties in object. "Or maybe filter is not a proper way here." It's absolutely the right way. You just need to sum the values of expenses inside the filter callback. – Felix Kling Commented Nov 7, 2018 at 18:45
  • const result = arr.filter(obj => Object.values(obj.expenses).every(expense => expense > 45)) – Pavlo Commented Nov 7, 2018 at 18:45
  • What code are you using to evaluate? – Neo Commented Nov 7, 2018 at 18:46
  • Change it to 25. How to iterate and get values of all expenses and filter that object? – Kamil Staszewski Commented Nov 7, 2018 at 18:47
  • 1 I want to receive objects where the sum of values inside a expenses object is above 25. That the example. Your code doesn't work : / – Kamil Staszewski Commented Nov 7, 2018 at 18:50
 |  Show 3 more ments

5 Answers 5

Reset to default 10

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);

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 ment, 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

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);

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

A possible solution might be:

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

本文标签: javascriptFiltering array with objects inside an objectStack Overflow