【问题标题】:Filter things with changeable arguments过滤具有可变参数的事物
【发布时间】:2017-09-02 13:00:08
【问题描述】:
let products = [
{
    "name": "Lenovo",
    "price": "18000",
    "model": "v580c"
},
{
    "name": "Apple",
    "price": "30000",
    "model": "Iphone 6"
},
{
    "name": "Nikon",
    "price": "25000",
    "model": "G290"
}]

我需要使用getProduct 函数过滤我的products 数组,该函数接受可变的参数列表。 参数可以是 产品 的名称和/或 minPricema​​xPrice 和/或 模型 中的价格>.

function getProduct(productName, minPrice, maxPrice, productModel) {

    return products.filter(product => {
        return product.price < maxPrice && product.price > minPrice && product.name == productName;
    });
}

console.log(getProduct("Apple", 3540, 3000000000));
console.log(getProduct("Lenovo", 3540, 3000000000, "v580c"));

【问题讨论】:

    标签: javascript function object filter arguments


    【解决方案1】:

    如果您不需要搜索多个项目,您可以使用具有特殊结构的对象进行搜索。该提案使用了一个对象,具有这种结构进行过滤:

    { 
        name: 'Apple',
        price: {
            min: 3540,  // both or a single border is possible
            max: 60000
        },
        model: function (s) { return s.match(/s/); } // just search for a single letter
    }
    

    算法查找search 中的每个属性,如果所有比较结果为真,则将该元素添加到结果集中。

    function filter(array, search) {
        return array.filter(function (a) {
            return Object.keys(search).every(function (k) {
                return (
                    a[k] === search[k] ||
                    typeof search[k] === 'object' && (
                        ('min' in search[k]) && ('max' in search[k]) && search[k].min <= a[k] && a[k] <= search[k].max ||
                        ('min' in search[k]) !== ('max' in search[k]) && (search[k].min <= a[k] || a[k] <= search[k].max)
                    ) ||
                    typeof search[k] === 'function' && search[k](a[k])
                );
            });
        });
    }
    
    var products = [{ name: "Lenovo", price: "18000", model: "v580c" }, { name: "Apple", price: "30000", model: "Iphone 6" }, { name: "Nikon", price: "25000", model: "G290" }, { name: "Foo", price: "10", model: "a1" }, { name: "Foo", price: "20", model: "a2" }, { name: "Foo", price: "30", model: "a3" }, { name: "Foo", price: "40", model: "a4" }, { name: "Foo", price: "50", model: "a5" }, { name: "Foo", price: "60", model: "a6" }, { name: "Foo", price: "70", model: "a7" }, { name: "Foo", price: "80", model: "a8" }, { name: "Foo", price: "90", model: "a9" }];
    
    console.log(filter(products, { name: 'Foo', price: { min: 60 } }));
    console.log(filter(products, { name: 'Foo', price: { max: 40 } }));
    console.log(filter(products, { name: 'Foo', price: { min: 40, max: 60 } }));
    console.log(filter(products, { name: 'Apple', price: { min: 3540, max: 60000 } }));
    console.log(filter(products, { name: 'Lenovo', price: { min: 3540, max: 60000 }, model: 'v580c' }));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 为什么我没有想到minmax。 +1
    • 只是一个建议,因为您编写了一个非常通用的代码,检查search[k] === 'object' 的最小值/最大值看起来不正确。您可以改为检查密钥。
    • @Rajesh,这只是一个开放 API 的想法。这取决于用途,需要哪些参数,这是一个建议,而不是最终产品(一如既往:-))
    • @Rajesh, in 仅适用于对象。如果没有对象,你会得到Uncaught TypeError: Cannot use 'in' operator to search for ... in ...
    • 很抱歉,这是我第一次想到,我会使用我的代码。 minmax 增加了很多条件。为单独的查询条件添加单独的对象将使 API 保持简单并使查询更具可配置性。但它只是我的 POV。可能有些事情我可能错过了,因此得出了这个结论,但我想失败和错误有助于我们学习。 :-) 周末愉快。
    【解决方案2】:

    您可以发送一个参数数组作为参数并编写一个逻辑来相应地处理它们。

    示例:

    function getProduct(array, params){
      var list = array.filter(function(o){
        return params.every(function(kv){
          if(o.hasOwnProperty(kv.key)){
            var cur = o[kv.key];
            switch (kv.operation){
              case ">":     return cur > kv.value 
              case "<":     return cur < kv.value 
              case "in":    return cur.indexOf(kv.value) > -1
              case "regex": return kv.value.test(cur)
              default:      return cur === kv.value 
            }
          }
        })
      });
      
      console.log(list);
      return list;
    }
    
    var products=[{name:"Lenovo",price:"18000",model:"v580c"},{name:"Apple",price:"30000",model:"Iphone 6"},{name:"Nikon",price:"25000",model:"G290"}];
    
    getProduct(products, [{key:"name", value: "Nikon"}])
    getProduct(products, [
      {key:"price", value: 20000, operation: ">"},
      {key:"price", value: 40000, operation: "<"}
    ])
    
    getProduct(products, [{key:"name", value: "e", operation: "in"}])
    getProduct(products, [{key:"model", value: /\d{2,}/g, operation: "regex"}])

    【讨论】:

      猜你喜欢
      • 2014-07-08
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多