使用动态布尔运算符筛选对象列表

本文关键字:筛选 对象 列表 运算符 布尔 动态 | 更新日期: 2023-09-27 17:51:21

我有这个方法:

private static List<ObjectA> ListItemsToShow(IEnumerable<ObjectA> listObjectB, 
                                             string _rarity, 
                                             string _type, 
                                             string _color,
                                             int? _quantity, 
                                             int? _sold, 
                                             string _quantitySymbol,
                                             string _soldSymbol)
{
    List<ObjectA> listToReturn = (from item in listObjectB 
                                  where _rarity == "All" || item.rarity == _rarity
                                  where _type == "All" || item.Type.Contains(_type) 
                                  where _color == "All" || item.Color.Contains(_color) 
                                  where _quantity == null || item.NbInStock == (int)_quantity
                                  where _sold == null || item.QtySold == (int)_sold
                                  select item).ToList();
    return listToReturn;
}

到目前为止,它的工作是:基于静态对象列表,它返回可以从原始对象列表中过滤的内容。

现在我想添加一个动态参数:quantitySymbol和soldSymbol。每个选项都是以下选项之一:

  • >
  • & lt;
  • > =
  • & lt; =

因此,我可以得到,例如,NbInStock<, >, <=>=的所有项目,而不是原始列表中保留的项目。对于QtySold属性也是如此。

我不知道如何在linq语句中做到这一点,我需要帮助来解决这个问题。

使用动态布尔运算符筛选对象列表

您可以使用函数进行过滤:

List<ObjectA> ItemsToShow(IEnumerable<ObjectA> listObjectB, Func<int,bool> stockFilter) {
  return (
    from item in listObjectB
    where (stockFilter == null || stockFilter(item.NbInStock)
    select item
  ).ToList();
}

,并像这样使用:

ItemsToShow(data, stock => (stock <= 10));
ItemsToShow(data, stock => (stock == 25));
ItemsToShow(data, stock => (stock > 3));
ItemsToShow(data, null); // does not use a stock filter

如果你需要从一个字符串创建股票过滤器,你可以使用工厂函数:

Func<int,bool> CreateCompareFilter(string op, int? quantity) {
   if(quantity == null) return null;
   if(op == "==") return x => (x == quantity);
   if(op == "<") return x => (x < quantity);
   ...
   return null;
}

那么你可以写

ItemsToShow(data, CreateCompareFilter("==",10));

所以总的来说是这样的:

private static List<ObjectA> ListItemsToShow(IEnumerable<ObjectA> listObjectB, 
                                             string _rarity, 
                                             string _type, 
                                             string _color,
                                             Func<int,bool> _stockFilter,
                                             Func<int,bool> _soldFilter)
{
    return (
        from item in listObjectB 
        where _rarity == "All" || item.rarity == _rarity
        where _type == "All" || item.Type.Contains(_type) 
        where _color == "All" || item.Color.Contains(_color) 
        where _stockFilter == null || _stockFilter(item.NbInStock)
        where _soldFilter == null || _soldFilter(item.QtySold)
        select item
    ).ToList();
}
ListItemsToShow(data, rarity, type, color,
   CreateCompareFilter(_quantitySymbol,_quantity)
   CreateCompareFilter(_soldSymbol,_sold));