1

I have a JSON array and a search form with multiple filters. In this search form I have 4 select drop down fields for filtering. How can I search the JSON array based on what the user selects and then display the results after they hit the submit button?

For instance If the user selects "Burger" in the "Food Select Drop Down" field and "Coke" in the "Drink Select Drop Down" field. I want to be able to display all the restaurants that offer both of those items. Is this possible?

var restaurants = [
            {"restaurant" : { "name" : "McDonald's", "food" : "burger", "drink" : "coke", "content" : "Lorem ipsum dolor sit amet" }},
            {"restaurant" : { "name" : "KFC", "food" : "chicken", "drink" : "pepsi", "content" : "Lorem ipsum dolor sit amet" }},
            {"restaurant" : { "name" : "Pizza Hut",  "food" : "pizza", "drink" : "sprite", "content" : "Lorem ipsum dolor sit amet" }},
            {"restaurant" : { "name" : "Dominos",  "food" : "pizza", "drink" : "root beer", "content" : "Lorem ipsum dolor sit amet" }},
            {"restaurant" : { "name" : "Popeyes",  "food" : "chicken", "drink" : "mist", "content" : "Lorem ipsum dolor sit amet" }}
          ];
4
  • You can iterate through your JSON array and do conditional filtering where appropriate. Do you need an example for this? If so, please give us an example of your JSON array. You can add this in your post directly. Commented Dec 31, 2013 at 1:17
  • thank you for the quick reply. i edited my post and added an example of my json array. Commented Dec 31, 2013 at 1:26
  • Since you aren't using angular.js I won't put this as an answer but I'd recommend using it for this particular case. Here is a live demo: jsfiddle.net/lacoolj/UACue and the documentation can be found here: docs.angularjs.org/tutorial/step_03 Commented Dec 31, 2013 at 2:10
  • Closer inline to your question, this would fit as a very basic starter: jsfiddle.net/lacoolj/2TvLH Commented Dec 31, 2013 at 2:13

3 Answers 3

2

One way to filter the array is the following

function filter( restaurants, food, drink) { 

    var result = [];

    for( var i= 0, len = restaurants.length; i < len; i++) {
        var el = restaurants.restaurant[i];

        if( el.food === food && el.drink === drink ) {
            result.push( el );
        }
    }

    return result;
}

A more functional way

You can use the filter method defined in the Array prototype

function customFilter(food, drink) {
   return function(el) {
      var r = el.restaurant;
      return r.food === food && r.drink === drink;
   }
}

restaurants.filter( customFilter('Burger', 'Coke') );

Sophisticated, general use filter

function customFilter(values) {
   return function(el) {
      var r = el.restaurant;
      var keys = Object.keys( values );
      var answer = true;

      for( var i = 0, len = keys.length; i < len; i++) {
          if( r[keys[i]] !== values[keys[i]] ) {
              answer = false;
              break;
          }
      }

      return answer;
   }
}

restaurants.filter( customFilter({'food':'Burger', 'drink': 'Coke'}) );    
Sign up to request clarification or add additional context in comments.

3 Comments

missing restaurant property for each object
ooh :P, i shall fix it
Is the returned object a reference to the original array object? I need to modify an array element in the original array
1

JavaScript has a native Array.prototype.filter which accepts a function. You simply want to generate this function when a user chooses the inputs, for example

function filter(a, food, drink) {
    food = food ? food.toLowerCase() : 0;
    drink = drink ? drink.toLowerCase() : 0;
    return a.filter(function (e) {
        if (food && e.restaurant.food.toLowerCase().indexOf(food) === -1)
            return false;
        if (drink && e.restaurant.drink.toLowerCase().indexOf(drink) === -1)
            return false;
        return true;
    });
}

filter(restaurants, 'burger', 'coke');
// [{"restaurant":{"name":"McDonald's","food":"burger","drink":"coke","content":"Lorem ipsum dolor sit amet"}}]

Comments

0

I've gave my vote to Igor's answer, but, because I wanted to put a full example in jsfiddle, here you go: http://jsfiddle.net/jeffrenaud/JDYMt/

I've added the possibility to have an 'Any' options, so that there's no filter on a particular element.

Here's a summary:

HTML:

<label for="food">Food:</label>
<select id="food">
    <option value="">Any</option>
    <option value="burger">Burger</option>
    <option value="chicken">Chicken</option>
    <option value="pizza">Pizza</option>
</select>

<label for="drink">Drink:</label>
<select id="drink">
    <option value="">Any</option>
    <option value="coke">Coke</option>
    <option value="pepsi">Pepsi</option>
    <option value="sprite">Sprite</option>
    <option value="root beer">Root beer</option>
    <option value="mist">Mist</option>
</select>

<ul id="result"></ul>

JavaScript:

var restaurants = [
    {
        "restaurant": {
            "name": "McDonald's",
            "food": "burger",
            "drink": "coke",
            "content": "Lorem ipsum dolor sit amet"
        }
    },
    {
        "restaurant": {
            "name": "KFC",
            "food": "chicken",
            "drink": "pepsi",
            "content": "Lorem ipsum dolor sit amet"
        }
    },
    {
        "restaurant": {
            "name": "Pizza Hut",
            "food": "pizza",
            "drink": "sprite",
            "content": "Lorem ipsum dolor sit amet"
        }
    },
    {
        "restaurant": {
            "name": "Dominos",
            "food": "pizza",
            "drink": "root beer",
            "content": "Lorem ipsum dolor sit amet"
        }
    },
    {
        "restaurant": {
            "name": "Popeyes",
            "food": "chicken",
            "drink": "mist",
            "content": "Lorem ipsum dolor sit amet"
        }
    }
  ];

var $food = $('#food'),
    $drink = $('#drink'),
    $result = $('#result');

$food.change(function () {
    onChange();
});

$drink.change(function () {
    onChange();
});

function onChange() {
    var findedRestaurants = findRestaurants();
    showRestaurants(findedRestaurants);
}

function findRestaurants() {
    return filter($food.find('option:selected').val(), $drink.find('option:selected').val());
}

function filter(food, drink) {
    var result = [];

    for (var i = 0; i < restaurants.length; i++) {
        var restaurant = restaurants[i].restaurant;
        if ((!food || restaurant.food === food) && (!drink || restaurant.drink === drink)) {
            result.push(restaurant);
        }
    }

    return result;
}

function showRestaurants(restaurants) {
    $result.empty();
    for (var i = 0; i < restaurants.length; i++) {
        $result.append($('<li>' + restaurants[i].name + '</li>'));
    }
}

onChange();

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.