1

I have an array of objects

var data = [
    {
      "body_focus": "upper",
      "difficulty": "three",
      "calories_min": "122",
      "calories_max": "250"
    },
    {
      "body_focus": "upper",
      "difficulty": "three",
      "calories_min": "150",
      "calories_max": "280"
    },
    {
      "body_focus": "lower",
      "difficulty": "two",
      "calories_min": "100",
      "calories_max": "180"
    },
    {
      "body_focus": "total",
      "difficulty": "four",
      "calories_min": "250",
      "calories_max": "350"
    }
]

I want to filter that array of objects against another object

var myObj = {
    "upper": true,
    "three": true
}

so now myObj has a key "upper" and "three" and their values are true. So based these values I want to make a function to get all the objects in the data array that its key "body_focus" has value of "upper" and "difficulty" key that has a value of "three"

so the function should return only these objects

[
    {
      "body_focus": "upper",
      "difficulty": "three",
      "calories_min": "122",
      "calories_max": "250"
    },
    {
      "body_focus": "upper",
      "difficulty": "three",
      "calories_min": "150",
      "calories_max": "280"
    }
]

this is how I tried to approach the problem

var entry;
var found = [];
for (var i = 0; i < data.length; i++) {
    entry = data[i];
    for(var key in myObj) {
        if(entry.body_focus.indexOf(key) !== -1) {
            found.push(entry);
            break;  
        }
    }
}

my code above only checks for the key body_focus , so how can I check for both body_focus and difficulty ? it might seem silly but I've been stuck for hours and can't find a solution

3
  • 1
    why not use the keys with the value as search criteria, like { "body_focus": "upper", "difficulty": "three" }? Commented Dec 2, 2016 at 13:53
  • I think you are vaguely looking for $.grep...but won't be possible with your current obj structure Commented Dec 2, 2016 at 13:55
  • It's better to use lodash for this kind of stuff. Commented Dec 2, 2016 at 14:04

5 Answers 5

2

You could use an object for searching which gives the keys and the wanted values, like

search = {
    body_focus: "upper",
    difficulty: "three"
}

then iterate through the array and check all properties of search with the values of the actual object. Return true if all search criteria matches.

var data = [{ body_focus: "upper", difficulty: "three", calories_min: "122", calories_max: "250" }, { body_focus: "upper", difficulty: "three", calories_min: "150", calories_max: "280" }, { body_focus: "lower", difficulty: "two", calories_min: "100", calories_max: "180" }, { body_focus: "total", difficulty: "four", calories_min: "250", calories_max: "350" }],
    search = { body_focus: "upper", difficulty: "three" },
    result = data.filter(function (o) {
        return Object.keys(search).every(function (k) {
            return o[k] === search[k];
        });
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

0

This should do the trick I think.

var myObj = {
    "upper": true,
    "three": true
}
var found = [];
for (var i = 0; i < data.length; i++) {
    entry = data[i];
    if(myObj[entry.body_focus] && myObj[entry.difficulty]) {
      found.push(entry);
    }
}

With myObj[entry.body_focus] you are checking if the myObj has the property upper and if it's true. Same with difficulty.

2 Comments

so it's okay to have difficulty as 'upper' and body_focus as 'three'?
Yea, well it would break. But why would he have the data interchanged...
0

This solution is using a combination of Array.prototype.filter and Array.prototype.every to match all the values in your data object with the keys in the param object.

var data = [
  {"body_focus": "upper", "difficulty": "three", "calories_min": "122", "calories_max": "250"}, 
  {"body_focus": "upper","difficulty": "three","calories_min": "150","calories_max": "280"},
  {"body_focus": "lower","difficulty": "two","calories_min": "100","calories_max": "180"}, 
  {"body_focus": "total","difficulty": "four","calories_min": "250","calories_max": "350"}
]

var params = {
  "upper": true,
  "three": true
}

function filter(params, data) {
  const keys = Object.keys(params)
  return data.filter(item =>
    keys.every(value => ~Object.values(item).indexOf(value))
  )
}


console.log(
  filter(params, data)
)
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

Comments

0

Nina's answer should work for you. But in case you are interested, another way to do it:

var data = [{
  "body_focus": "upper",
  "difficulty": "three",
  "calories_min": "122",
  "calories_max": "250"
}, {
  "body_focus": "upper",
  "difficulty": "three",
  "calories_min": "150",
  "calories_max": "280"
}, {
  "body_focus": "lower",
  "difficulty": "two",
  "calories_min": "100",
  "calories_max": "180"
}, {
  "body_focus": "total",
  "difficulty": "four",
  "calories_min": "250",
  "calories_max": "350"
}];

var search = { 
  body_focus: "upper", difficulty: "three" 
};

var results=$.grep(data,function(datum,index){
  var sat=true;
  Object.keys(search).forEach(function(el){
    if(datum[el]!=search[el])
      {
        sat=false;
        return false;
      }
  });
  return sat;
});
console.log(results);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

The point being you could use $.grep to write a custom filter function and check some condition using the first parameter 'datum' or the second 'index' and return true to indicate filter match or false to indicate otherwise

Comments

0

it would be a good idea to change your myObj object's structure to be more of

let myObj = 
{
    body_focus: "upper",
    difficulty: "three"
}     

as your search object. (as it was mentioned in one of the answers)

you can then use filter on your original array of objects to get what you need.

let results = data.filter(item => item.body_focus === myObj.body_focus 
                               && item.difficulty === myObj.difficulty);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.