Home > front end >  Filter a List based on an array of conditions
Filter a List based on an array of conditions

Time:07-14

I'm currently obtaining a set of data via an API and I display it as a table on a cshtml page

Item 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.

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

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. Any pointers on what I'm doing wrong in the process?

CodePudding user response:

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.

CodePudding user response:

But also each column has OR logic 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:

Item 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.

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));
            }
  • Related