【问题标题】:Filter an array with multiple conditions fetched from user过滤具有从用户获取的多个条件的数组
【发布时间】:2020-10-23 13:11:54
【问题描述】:

我试图弄清楚如何根据用户的输入过滤一组对象。目前,我的搜索 btn 函数处理程序上有一个简单的 array.filter,见下文:

数组示例:

const items = [
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Pad Thai',
        imageUrl:
            'https://www.2foodtrippers.com/wp-content/uploads/2016/08/Delicious-Thai-Food-Pad-Thai.jpg.webp',
        country: 'Thailand',
        price: 5,
        description: 'Street food in Bankok',
        category: 'Food/Beverage',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Canned coffee',
        imageUrl:
            'https://331mrnu3ylm2k3db3s1xd1hg-wpengine.netdna-ssl.com/wp-content/uploads/2015/08/Sprudge-VendingMachineCoffee-KateBeard-sprudgevending-3-740x493.jpg',
        country: 'Japan',
        price: 3.5,
        description: 'Had to have one of this in Tokyo',
        category: 'Food/Beverage',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Scooter day rental',
        imageUrl:
            'https://anomadsdream.com/wp-content/uploads/2013/05/SAM_1859.jpg',
        country: 'Vietnam',
        price: 7.5,
        description:
            'Cheap rental bike, Ko Thao. This is average price around Thailand',
        category: 'Transport',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Bottle of Water Price',
        imageUrl:
            'https://2reb5l2d3joj3y7m8y2f5ptbefc-wpengine.netdna-ssl.com/order/files/2017/11/B1.jpg',
        country: 'Thailand',
        price: 5,
        description: 'Street food Pad Thai',
        category: 'Food/Beverage',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Gold Ice Cream',
        imageUrl:
            'https://kaname-inn.com/wp/wp-content/uploads/2018/05/IMG_4388_11.jpg',
        country: 'Japan',
        price: 5,
        description: 'Delicious golden ice cream in Kyoto',
        category: 'Food/Beverage',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Buddah bracelet',
        imageUrl:
            'https://c7.alamy.com/comp/M8XGMD/seoul-south-korea-march-6-2018-buddhist-bracelet-on-shop-at-jogyesa-M8XGMD.jpg',
        country: 'Japan',
        price: 5,
        description: 'Bought this while street shopping in Seoul',
        category: 'Food/Beverage',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Suvarnabhumi Taxi',
        imageUrl:
            'https://static.bangkokpost.com/media/content/20160507/c1_962249_160507092902.jpg',
        country: 'Thailand',
        price: 5,
        description: 'Taxi from the center Bankok',
        category: 'Food/Beverage',
    },
    {
        id: Math.random().toFixed(5),
        itemTitle: 'Vietnamese Coffee',
        imageUrl:
            'https://thewoksoflife.com/wp-content/uploads/2017/12/vietnamese-coffee-7.jpg',
        country: 'Vietnam',
        price: 3.5,
        description: 'Delicious! prices change but this is the average',
        category: 'Food/Beverage',
    },
];

函数处理程序

const searchBtnHandler = () => {
    const itemElements = document.getElementById('cards-hook').children;
    const countryValue = countryFilterAccess.value;
    const searchCategory = searchCategoryMenu.value;

    const filteredItems = items.filter((item) => {
        return item.country === countryValue && item.category === searchCategory;

    });
    console.log(filteredItems);
};

国家价值和搜索类别是从页面中获取的。假设用户同时提供过滤器(国家和类别),我拥有的过滤器可以工作。但是,我还想让用户选择其中一个过滤器。我已经通过“if statements”尝试过这个,但数组返回空或“奇怪”的过滤器设置。

我想要的如下:

国家/地区为空 - 提供类别
给定国家 - 类别留空

有人可以帮忙吗?我看过其他回复,但他们认为过滤条件已经给出,这不是我的情况。

谢谢!

【问题讨论】:

  • “我已经通过“if statements”尝试过这个,但是数组返回空或“奇怪”的过滤器设置” - 请添加您的尝试,以便我们帮助您修复它.
  • 使用 || 而不是 && 应该可以在您的过滤器中使用

标签: javascript


【解决方案1】:

如果你想创建一个动态过滤器,我建议你创建一个类似于 List item 的对象,但带有你要过滤的 props。例如

const items = [
{
    id: Math.random().toFixed(5),
    itemTitle: 'Pad Thai',
    imageUrl:
        'https://www.2foodtrippers.com/wp-content/uploads/2016/08/Delicious-Thai-Food-Pad-Thai.jpg.webp',
    country: 'Thailand',
    price: 5,
    description: 'Street food in Bankok',
    category: 'Food/Beverage',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Canned coffee',
    imageUrl:
        'https://331mrnu3ylm2k3db3s1xd1hg-wpengine.netdna-ssl.com/wp-content/uploads/2015/08/Sprudge-VendingMachineCoffee-KateBeard-sprudgevending-3-740x493.jpg',
    country: 'Japan',
    price: 3.5,
    description: 'Had to have one of this in Tokyo',
    category: 'Food/Beverage',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Scooter day rental',
    imageUrl:
        'https://anomadsdream.com/wp-content/uploads/2013/05/SAM_1859.jpg',
    country: 'Vietnam',
    price: 7.5,
    description:
        'Cheap rental bike, Ko Thao. This is average price around Thailand',
    category: 'Transport',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Bottle of Water Price',
    imageUrl:
        'https://2reb5l2d3joj3y7m8y2f5ptbefc-wpengine.netdna-ssl.com/order/files/2017/11/B1.jpg',
    country: 'Thailand',
    price: 5,
    description: 'Street food Pad Thai',
    category: 'Food/Beverage',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Gold Ice Cream',
    imageUrl:
        'https://kaname-inn.com/wp/wp-content/uploads/2018/05/IMG_4388_11.jpg',
    country: 'Japan',
    price: 5,
    description: 'Delicious golden ice cream in Kyoto',
    category: 'Food/Beverage',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Buddah bracelet',
    imageUrl:
        'https://c7.alamy.com/comp/M8XGMD/seoul-south-korea-march-6-2018-buddhist-bracelet-on-shop-at-jogyesa-M8XGMD.jpg',
    country: 'Japan',
    price: 5,
    description: 'Bought this while street shopping in Seoul',
    category: 'Food/Beverage',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Suvarnabhumi Taxi',
    imageUrl:
        'https://static.bangkokpost.com/media/content/20160507/c1_962249_160507092902.jpg',
    country: 'Thailand',
    price: 5,
    description: 'Taxi from the center Bankok',
    category: 'Food/Beverage',
},
{
    id: Math.random().toFixed(5),
    itemTitle: 'Vietnamese Coffee',
    imageUrl:
        'https://thewoksoflife.com/wp-content/uploads/2017/12/vietnamese-coffee-7.jpg',
    country: 'Vietnam',
    price: 3.5,
    description: 'Delicious! prices change but this is the average',
    category: 'Food/Beverage',
},
];


// filter function
const filterFn = (filters) => {
  const filteredItems = items.filter((item) => !Boolean(Object.entries(filters).find(([key, value]) => item[key] !== value)))
  return filteredItems
}

const filtersByCountryAndCategory = {
    country: 'Vietnam',
    category: 'Food/Beverage',
}
const filtersByCountryAndPrice = {
  price: 5,        
  category: 'Food/Beverage',
}

console.log("******* BY COUNTRY AND CATEGORY **********");
console.log(filterFn(filtersByCountryAndCategory));

console.log("******* BY CATEGORY AND PRICE **********");
console.log(filterFn(filtersByCountryAndPrice));


 

【讨论】:

    【解决方案2】:

    我的最终代码有效!见最终截图:

    const filteredItems = (countryValue, searchCategory) => {
        if (countryValue && searchCategory) {
            return items.filter(
                (item) =>
                    item.country === countryValue && item.category === searchCategory
            );
        }
        if (countryValue) {
            return items.filter((item) => item.country === countryValue);
        }
        return items.filter((item) => item.category === searchCategory);
    };
    
    const searchBtnHandler = () => {
        const itemElements = document.getElementById('cards-hook').children; //this is for the dom
        const countryValue = countryFilterAccess.value.trim();
        const searchCategory = searchCategoryMenu.value.trim();
        const results = filteredItems(countryValue, searchCategory);
    
        console.log(results);
    };
    
    

    【讨论】:

      【解决方案3】:

      您必须为每个条件使用 if 案例,这是一个示例:

      const items = [{
          id: Math.random().toFixed(5),
          itemTitle: 'Pad Thai',
          imageUrl: 'https://www.2foodtrippers.com/wp-content/uploads/2016/08/Delicious-Thai-Food-Pad-Thai.jpg.webp',
          country: 'Thailand',
          price: 5,
          description: 'Street food in Bankok',
          category: 'Food/Beverage',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Canned coffee',
          imageUrl: 'https://331mrnu3ylm2k3db3s1xd1hg-wpengine.netdna-ssl.com/wp-content/uploads/2015/08/Sprudge-VendingMachineCoffee-KateBeard-sprudgevending-3-740x493.jpg',
          country: 'Japan',
          price: 3.5,
          description: 'Had to have one of this in Tokyo',
          category: 'Food/Beverage',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Scooter day rental',
          imageUrl: 'https://anomadsdream.com/wp-content/uploads/2013/05/SAM_1859.jpg',
          country: 'Vietnam',
          price: 7.5,
          description: 'Cheap rental bike, Ko Thao. This is average price around Thailand',
          category: 'Transport',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Bottle of Water Price',
          imageUrl: 'https://2reb5l2d3joj3y7m8y2f5ptbefc-wpengine.netdna-ssl.com/order/files/2017/11/B1.jpg',
          country: 'Thailand',
          price: 5,
          description: 'Street food Pad Thai',
          category: 'Food/Beverage',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Gold Ice Cream',
          imageUrl: 'https://kaname-inn.com/wp/wp-content/uploads/2018/05/IMG_4388_11.jpg',
          country: 'Japan',
          price: 5,
          description: 'Delicious golden ice cream in Kyoto',
          category: 'Food/Beverage',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Buddah bracelet',
          imageUrl: 'https://c7.alamy.com/comp/M8XGMD/seoul-south-korea-march-6-2018-buddhist-bracelet-on-shop-at-jogyesa-M8XGMD.jpg',
          country: 'Japan',
          price: 5,
          description: 'Bought this while street shopping in Seoul',
          category: 'Food/Beverage',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Suvarnabhumi Taxi',
          imageUrl: 'https://static.bangkokpost.com/media/content/20160507/c1_962249_160507092902.jpg',
          country: 'Thailand',
          price: 5,
          description: 'Taxi from the center Bankok',
          category: 'Food/Beverage',
        },
        {
          id: Math.random().toFixed(5),
          itemTitle: 'Vietnamese Coffee',
          imageUrl: 'https://thewoksoflife.com/wp-content/uploads/2017/12/vietnamese-coffee-7.jpg',
          country: 'Vietnam',
          price: 3.5,
          description: 'Delicious! prices change but this is the average',
          category: 'Food/Beverage',
        },
      ];
      
      
      function filteredItems(countryValue, searchCategory) {
        if (countryValue && searchCategory) {
          return items.filter(item => item.country === countryValue && item.category === searchCategory);
        }
        if (countryValue) {
          return items.filter(item => item.country === countryValue);
        }
        return items.filter(item => item.category === searchCategory);
      
      }
      
      //example 1
      let countryValue = "Vietnam"
      let searchCategory = ""
      console.log(filteredItems(countryValue, searchCategory));
      
      //example 2
      let country = "Vietnam"
      let category = "Transport"
      console.log(filteredItems(country, category));
      
      //example 3
      countryValue = ""
      searchCategory = "Transport"
      console.log(filteredItems(countryValue, searchCategory));

      【讨论】:

      • 是的!!!!这行得通!非常感谢兄弟:)!我只需要将它存储到一个常量中,然后我就可以使用该数组来完成更多任务!
      【解决方案4】:

      试试这个:

          const filteredItems = items.filter((item) => {
              return (countryValue === "" || item.country === countryValue) && (searchCategory === "" || item.category === searchCategory);
          });
      

      (编辑:HTML 当其中没有值时返回空字符串)

      【讨论】:

      • 这是错误的,如果你只输入一个国家你应该过滤所有国家如果你只输入类别你应该得到所有这些类别
      • 嗨@EugenSunic,但这就是这个条件所达到的!如果用户为该属性指定了值,它只会过滤该属性。
      • 感谢您的帮助!我尝试使用此代码,但是当我将输入与 null 进行比较时,我得到 false 与输入值,不知道为什么...如果字符串为空,我期待 null 但是当我将其与 null 进行比较时控制台会产生 false (console.log(countryvalue === null) 我应该改用 == 吗?谢谢!
      • 我尝试了以下但国家和类别不起作用...有什么想法吗?常量过滤项目 = items.filter((item) => { return ( item.country === countryValue || item.category === searchCategory || (item.country === countryValue && item.category === searchCategory) );
      • 抱歉,回答延迟。我刚刚测试过,输入将在空时返回一个空字符串""。我最后说您可能需要检查其他值,因为我没有时间尝试自己,对此感到抱歉。你看的是(countryValue === "" || item.country === countryValue) && (searchCategory === "" || item.category === searchCategory);
      猜你喜欢
      • 2021-07-05
      • 2019-03-02
      • 2019-11-20
      • 1970-01-01
      • 2021-01-26
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2018-09-30
      相关资源
      最近更新 更多