javascript 如何使用搜索过滤器表单搜索 JSON 数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20850204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 19:26:56  来源:igfitidea点击:

How to search JSON array with search filter form?

javascriptjqueryarraysjson

提问by user2402492

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?

我有一个 JSON 数组和一个带有多个过滤器的搜索表单。在此搜索表单中,我有 4 个用于过滤的选择下拉字段。如何根据用户选择的内容搜索 JSON 数组,然后在他们点击提交按钮后显示结果?

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

回答by Igor ?ar?evi?

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 filtermethod defined in the Array prototype

可以使用Array 原型中定义的filter方法

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

回答by Paul S.

JavaScripthas a native Array.prototype.filterwhich accepts a function. You simply want to generate this function when a user chooses the inputs, for example

JavaScript有一个本机Array.prototype.filter,它接受一个函数。例如,您只想在用户选择输入时生成此函数

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

回答by Jeff Renaud

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/

我已经对 Igor 的回答投了票,但是,因为我想在 jsfiddle 中放一个完整的例子,所以你去: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:

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:

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