简体   繁体   中英

How to only add items to a list that haven't been added before? (C# - ASP.NET)

I have a list that is being populated with the summed quantities of specific product ID's, for example:

My table:

在此处输入图片说明

My program checks for a user input and then compares that user input to the Quantity column in the table - once a match is found, the program checks for the ProductID of the matched quantity, and then adds ALL the quantities relating to that matched ProductID.

For example, if a user enters 2, the program will check for all the values in the Quantity column greater than or equal to 2 - so in this case, the first row to be found would be row 2 (which has a productID of 9 and a quantity of 2). The program should now search for ALL productID's equal to 9 and then sum their individual quantities (which will be 3 in this case, as the ProductID 9 appears only twice, with the quantities 2 and 1 respectively), and then save that final summed quantity (3) into the list. And then the program should continue to row 3 (which has a productID of 8 and a quantity of 3). The program should now search for ALL productID's equal to 8 and then sum their individual quantities (which will be 9 in this case, as the ProductID 8 appears three times, with the quantities 3 and 3 and 3 respectively), and then save that final summed quantity (9) into the list. And then the program should SKIP row 4, because the ProductID of 9 has already been dealt with - and so on and so forth.

So far i have tried this:

var dynamicReader = DBAccessor.InvoiceLines.Where(xx => xx.Quantity >= quantitySelected).Select(yy => yy.ProductID);

            foreach (var product in dynamicReader)
            {
                if (!quantityArrayList.Contains(product))
                {
                    quantityArrayList.Add(DBAccessor.InvoiceLines.Where(gg => gg.ProductID == product).Sum(g => g.Quantity));
                }
            }

If the user enters 2, the first 4 results using this method are correct, however, after that, the summed values fetched make little sense to me. Any help on this matter would be greatly appreciated.

It looks like you're not associating the ProductID with the Quantity stored in quantityArrayList . So, when you check quantityArrayList.Contains(product) you're not checking to see if that ProductID has already been processed, you're checking to see if there is a sum of quantities which match the ProductID .

I don't know what type quantityArrayList is, I'm assuming it's a List<int> . Instead, you should use a Dictionary where the key would be the ProductID and the value would be the sum of the Quantity .

Untested, but the updated code might look like...

Dictionary<int, int> productQuantities = new Dictionary<int, int>(); //I've changed the name, but this would replace quantityArrayList

var dynamicReader = DBAccessor.InvoiceLines.Where(xx => xx.Quantity >= quantitySelected).Select(yy => yy.ProductID);

foreach (var product in dynamicReader)
{
    if (!productQuantities.ContainsKey(product))
    {
        productQuantities.Add(product, DBAccessor.InvoiceLines.Where(gg => gg.ProductID == product).Sum(g => g.Quantity));
    }
}

I would use GroupBy with 2 values mapped to the grouping: Max and Sum . If the max quantity of one of the entries is greater than your desired amount, that grouping is 'in scope' and you want to get its sum. Like this:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    public class Program
    {
        public static void Main()
        {
            var productCounts = new List<ProductCount>{
                new ProductCount{ProductId = 10, Quantity = 1},
                new ProductCount{ProductId = 9, Quantity = 2},
                new ProductCount{ProductId = 8, Quantity = 3},
                new ProductCount{ProductId = 9, Quantity = 1},
                new ProductCount{ProductId = 7, Quantity = 2},
                new ProductCount{ProductId = 5, Quantity = 3},
                new ProductCount{ProductId = 8, Quantity = 3},
                new ProductCount{ProductId = 6, Quantity = 2}
            };
            
            var desiredMinimum = 3;
            
            var output = productCounts.GroupBy(i => i.ProductId)
                .Select(i => new
                        {
                            ProductId = i.Key,
                            Max = i.Max(j => j.Quantity),
                            Total = i.Sum(j => j.Quantity)
                        })
                .Where(i => i.Max >= desiredMinimum)
                .ToList();
            
            foreach(var outputItem in output){
                Console.WriteLine("ProductId: " + outputItem.ProductId + "; Total: " + outputItem.Total);
            }
        }
        internal class ProductCount
        {
            public int ProductId{get;set;}
            public int Quantity{get;set;}
        }
    }

See:

https://dotnetfiddle.net/HmMc4h

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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