如何通过选择标签中选择的数字过滤json数据

时间:2018-09-19 14:52:38

标签: javascript json ajax

假设我有这个json文件:

[
  {
    "restaurantName":"name1",
    "address":"restaurant1 address",
    "lat":lat1,
    "long":long1,
    "ratings":[
       {
          "stars":4,
          "comment":"good"
       },
       {
          "stars":5,
          "comment":"excellent"
       }
     ]
  },
  {
    "restaurantName":"name2",
    "address":"restaurant2 address",
    "lat":lat2,
    "long":long2,
    "ratings":[
       {
          "stars":4,
          "comment":"good"
       },
       {
          "stars":3,
          "comment":"ok"
       }
     ]
  } 
]

此html代码:

<select id="s1">
  <option value="0">0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>

<select id="s2">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
  <option value="5">5</option>
</select>

<button type="button" id="btn">filter</button>

问题是我找不到一种方法来过滤此数据并获取在选择标签中选择的两个数字之间具有星级评分的餐馆列表。

2 个答案:

答案 0 :(得分:3)

您可以使用函数absolute来对星星值求和,函数Array.reduce可以检查Array.filter的评级间隔。

from-to
let data = [  {    "restaurantName":"name1",    "address":"restaurant1 address",    "lat":1,    "long":1,    "ratings":[       {          "stars":4,          "comment":"good"       },       {          "stars":5,          "comment":"excellent"       }     ]  },  {    "restaurantName":"name2",    "address":"restaurant2 address",    "lat":1,    "long":1,    "ratings":[       {          "stars":4,          "comment":"good"       },       {          "stars":3,          "comment":"ok"       }     ]  } ],
    ratingFrom = 3, // from s1 select
    ratingTo = 4, // from s2 select
    result = data.filter(d => {
      let avg = d.ratings.reduce((a, r) => a + r.stars, 0) / d.ratings.length;
      return avg >= ratingFrom && avg <= ratingTo;
    });

console.log(result);

答案 1 :(得分:0)

首先,我建议检查Array.filter(...)Array.reduce(...)上的文档。 在下面的示例中,您可以看到解决问题的方法。

您可以通过使用Array.reduce(...)对星星的值求和来计算评分的平均值,然后可以将计算出的值与<input type="text" id="txtcard1" size="4" runat="server" onkeyup="movetoNext(this, '<%= txtcard2.ClientID %>')" maxlength="4" /> <input type="text" id="txtcard2" size="4" runat="server" onkeyup="movetoNext(this, '<%= txtcard3.ClientID %>')" maxlength="4" /> 中的选定值进行比较,这就是{{简而言之就是3}}-此函数将返回一个新数组,其中包含满足预定条件的元素(在我们的示例中为<select>)。

@Ele已经提供了最短的解决方案,我在下面的示例中引入了一个附加的Array.filter(...),在这里不是必须的。不过,如果您怀疑它的功能-附加的avgRating >= minRating && avgRating <= maxRating;函数将为我返回一个仅包含评级本身的新数组,如果为map,它将为restaurant1

[4, 5]
const data = [{
    "restaurantName": "name1",
    "address": "restaurant1 address",
    "lat": 51.43434,
    "long": 51.43434,
    "ratings": [{
        "stars": 4,
        "comment": "good"
      },
      {
        "stars": 5,
        "comment": "excellent"
      }
    ]
  },
  {
    "restaurantName": "name2",
    "address": "restaurant2 address",
    "lat": 51.43434,
    "long": 51.43434,
    "ratings": [{
        "stars": 4,
        "comment": "good"
      },
      {
        "stars": 3,
        "comment": "ok"
      }
    ]
  }
];

document.getElementById('btn').addEventListener('click', () => {
  const filteredRestaurants = data.filter(entry => {
    const ratings = entry.ratings;
    const avgRating = ratings
      .map(rating => rating.stars)
      .reduce((prev, next) => {
        return prev + next;
      }, 0) / ratings.length;
    const minRating = document.getElementById('s1').value;
    const maxRating = document.getElementById('s2').value;

    return avgRating >= minRating && avgRating <= maxRating;
  });
  console.log(filteredRestaurants);
});