最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to search JSON array with search filter form? - Stack Overflow

programmeradmin1浏览0评论

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" }}
          ];

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" }}
          ];
Share Improve this question edited Dec 31, 2013 at 1:25 user2402492 asked Dec 31, 2013 at 1:14 user2402492user2402492 671 gold badge2 silver badges10 bronze badges 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. – Jeff Renaud 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. – user2402492 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 remend using it for this particular case. Here is a live demo: jsfiddle/lacoolj/UACue and the documentation can be found here: docs.angularjs/tutorial/step_03 – Deryck Commented Dec 31, 2013 at 2:10
  • Closer inline to your question, this would fit as a very basic starter: jsfiddle/lacoolj/2TvLH – Deryck Commented Dec 31, 2013 at 2:13
Add a ment  | 

3 Answers 3

Reset to default 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'}) );    

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"}}]

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/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();
发布评论

评论列表(0)

  1. 暂无评论