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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.