简体   繁体   English

根据条件数组过滤列表

[英]Filter a List based on an array of conditions

I'm currently obtaining a set of data via an API and I display it as a table on a cshtml page我目前正在通过 API 获取一组数据,并将其显示为 cshtml 页面上的表格

Item A项目 A Supplier供应商 Size尺寸 Material材料
Boxes盒子 Walmart沃尔玛 Small小的 Cardboard纸板
Boxes盒子 Costco好市多 Medium中等的 Cardboard纸板
Boxes盒子 Walmart沃尔玛 Small小的 Plastic塑料
Bags Target目标 Big大的 Leather皮革
Bags Walmart沃尔玛 Big大的 Plastic塑料

and I have 3 dropdowns each one with a catalogue corresponding to each column of my table.我有 3 个下拉列表,每个下拉列表都有一个与我的表的每一列对应的目录。

Each time one of the checkboxes on my dropdowns is clicked I have to filter the table.每次单击我的下拉列表中的一个复选框时,我都必须过滤表格。 So far my process is calling again the API to get the data then pass the selected values to my controller as an array to start applying filters with this function到目前为止,我的过程再次调用 API 以获取数据,然后将选定的值作为数组传递给我的控制器,以开始使用此函数应用过滤器

for (int filterPos = 0; filterPos < filterList.Count; filterPos++)
            {
                List<StockItemsModel> filtered = model;
                if (filterPos == 0)
                {
                    if (model.FindAll(e => e.Supplier.Contains(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        filtered = filtered.FindAll(e => e.Supplier.Equals(filterList.ElementAt(filterPos)));
                        tmp = filtered;
                        continue;
                    }
                    if (model.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        filtered = filtered.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos)));
                        tmp = filtered;
                        continue;
                    }
                    if (model.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        filtered = filtered.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos)));
                        tmp = filtered;
                        continue;
                    }
                    
                }
                else
                {
                    if (tmp.FindAll(e => e.Supplier.Contains(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        tmp = tmp.FindAll(e => e.Supplier.Equals(filterList.ElementAt(filterPos)));
                        continue;
                    }
                    else if (model.FindAll(e => e.Supplier.Contains(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        filtered = filtered.FindAll(e => e.Supplier.Equals(filterList.ElementAt(filterPos)));
                        foreach (StockItemsModel item in filtered)
                        {
                            tmp.Add(item);
                        }
                        continue;
                    }
                    if (tmp.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        tmp = tmp.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos)));
                        continue;
                    }
                    else if (model.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        filtered = filtered.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos)));
                        foreach (StockItemsModel item in filtered)
                        {
                            tmp.Add(item);
                        }
                        continue;
                    }
                    if (tmp.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        tmp = tmp.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos)));
                        continue;
                    }
                    else if (model.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos))).Count > 0)
                    {
                        filtered = filtered.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos)));
                        foreach (StockItemsModel item in filtered)
                        {
                            tmp.Add(item);
                        }
                        continue;
                    }
                }
            }

            model = tmp;

            return PartialView("_AddStockTable", model);
}

so far the first and second filters work all right, for example filtering [Plastic, Small] works like a charm and I get only two records, but for [Plastic,Small,Cardboard] then I get also two records instead of three.到目前为止,第一个和第二个过滤器工作正常,例如过滤 [Plastic, Small] 就像一个魅力,我只得到两条记录,但是对于 [Plastic,Small,Cardboard] 我也得到两条记录而不是三条记录。 Any pointers on what I'm doing wrong in the process?关于我在此过程中做错了什么的任何指示?

But also each column has OR logic ex size1 & (supplier1 or supplier2) & material1但每列也有 OR 逻辑 ex size1 & (supplier1 or supplier2) & material1

If so,for [Plastic,Small,Cardboard] ,you will get two records.It means Small&(Plastic or Cardboard) ,the result will be:如果是这样,对于[Plastic,Small,Cardboard] ,您将获得两条记录。这意味着Small&(Plastic or Cardboard) ,结果将是:

Item A项目 A Supplier供应商 Size尺寸 Material材料
Boxes盒子 Walmart沃尔玛 Small小的 Cardboard纸板
Boxes盒子 Walmart沃尔玛 Small小的 Plastic塑料

You can also use the following code to filter the data.Split filterList to SupplierfilterList , SizefilterList , MaterialfilterList ,and then filter the model with the lists.您还可以使用以下代码过滤数据。将 filterList filterListSupplierfilterList ​​lterList 、 SizefilterListMaterialfilterList ,然后使用列表过滤模型。

List<string> SupplierfilterList = new List<string>();
            List<string> SizefilterList = new List<string>();
            List<string> MaterialfilterList = new List<string>();
            List<StockItemsModel> filtered = model;
            for (int filterPos = 0; filterPos < filterList.Count; filterPos++) {
                if (model.FindAll(e => e.Supplier.Contains(filterList.ElementAt(filterPos))).Count > 0)
                {
                    SupplierfilterList.Add(filterList.ElementAt(filterPos));
                    continue;
                }
                if (model.FindAll(e => e.Size.Equals(filterList.ElementAt(filterPos))).Count > 0)
                {
                    SizefilterList.Add(filterList.ElementAt(filterPos));
                    continue;
                }
                if (model.FindAll(e => e.Material.Equals(filterList.ElementAt(filterPos))).Count > 0)
                {
                    MaterialfilterList.Add(filterList.ElementAt(filterPos));
                    continue;
                }
            }
            if (SupplierfilterList.Count > 0) {
                filtered = filtered.FindAll(e => new[] { e.Supplier }.Any(SupplierfilterList.Contains));
            }
            if (SizefilterList.Count > 0)
            {
                filtered = filtered.FindAll(e => new[] { e.Size }.Any(SizefilterList.Contains));
            }
            if (MaterialfilterList.Count > 0)
            {
                filtered = filtered.FindAll(e => new[] { e.Material }.Any(MaterialfilterList.Contains));
            }

If I understood correctly what you are trying to do is basically: if any value in the filter list is in any column then return.如果我理解正确你想要做的基本上是:如果过滤器列表中的任何值在任何列中,则返回。

I didn't try to find the bug in your code, because it looks like a total mess.我没有尝试在您的代码中找到错误,因为它看起来一团糟。

I would refactor to this:我会重构这个:

var r = model.FindAll(e => new [] { e.Supplier, e.Size, e.Material }.Any(filterList.Contains));
return PartialView("_AddStockTable", r);

One piece of advice, don't give more than one meaning to one single variable and don't use two variables for the same value, it will become harder to read and understand.一条建议,不要对一个变量赋予多个含义,也不要将两个变量用于同一个值,它会变得更难阅读和理解。 In your code model , tmp and filtered are all mixed together.在您的代码model中, tmpfiltered器都混合在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM