5

しばらくこれに苦労しています。

私は WebAPI の世界に足を踏み入れており、同じ名前で価格が異なる製品を含むことができるリストを持っています。私がする必要があるのは、価格の変動が発生した製品へのすべての参照を削除することです.

例えば。
name = "コーンフレーク" Price = "1.99M"
name = "コーンフレーク" Price = "1.89M"
name = "ライスクリスピー" Price = "2.09M"
name = "コーンフレーク" Price = "2.09M"

私の最終的なリストにコーンフレークは表示されません。

大量の書き込みがありましたが、製品を削除するのが早すぎて、どこで削除すればよいかわかりません。

public IEnumerable<Product> GetProductsByCategory(int Id)
    {
        List<Product> sourceProductList = products.Where(p => p.CategoryID == Id).ToList();
        List<Product> tempProducts = new List<Product>();
        List<Product> targetProductList = new List<Product>();

        foreach (var product in sourceProductList)
        {
            bool isInTempList = tempProducts.Any(x => x.Name == product.Name);
            if (!isInTempList)
            {
                tempProducts.Add(product);
            }
            else
            {
                Product tempProduct = product;
                bool isPriceDifferent = tempProducts.Where(y => y.Name == tempProduct.Name).Any(y => y.Price != tempProduct.Price);
                if (isPriceDifferent)
                {
                    tempProducts.RemoveAll(p => p.Name == product.Name); 
                    // too soon as I may have lots of products with the same name
                    // but need to remove based on product.Name
                }
            }
        }
        targetProductList.AddRange(tempProducts);

        return targetProductList;
    }

どんな助けでも大歓迎です。

注: 他の穀物が利用可能です

4

4 に答える 4

12

1 つの異なる価格を持つ製品のみを選択する次の LINQ 式を試してください。

var result = sourceProductList
    .GroupBy(x => x.Name)
    .Where(g => g.Select(x => x.Price).Distinct().Count() == 1)
    .Select(g => g.First());

オンラインで動作することを確認してください: ideone .

于 2012-10-11T13:18:51.437 に答える
2

これを試してください:

class Program
    {
        static void Main(string[] args)
        {
            var list = new List<Product>
                {
                    new Product() {Name = "Cornflakes", Price = 100},
                    new Product() {Name = "Cornflakes", Price = 200},
                    new Product() {Name = "Rice Krispies", Price = 300},
                    new Product() {Name = "Cornflakes", Price = 400}
                };

            var uniqueItems = list.Where(w => (!list.Any(l=>l.Name.Equals(w.Name) && l != w)));

        }

        public class Product
        {

            public string Name { get; set; }
            public decimal Price { get; set; }
        }
    }

結果として、「ライスクリスピー」アイテムは1つだけになります。あなたの場合、これらの不必要なことをする必要がないので、GroupByとDistinctを使ったソリューションよりも速く動作すると確信しています。

作業コード-http://ideone.com/X8A3v

于 2012-10-11T13:26:17.277 に答える
1

このようなもの(フリーハンドなので、構文が少し間違っている可能性があります):

var toRemove = sourceProductList
    .GroupBy(p => p.Name)
    .Where(g => g.Count() > 1)
    .SelectMany(g => g)
    .GroupBy(p => p.Price)
    .Where(g => g.Count() > 1)
    .SelectMany(g => g.Select(p => p.ID))
    .Distinct()
    .ToList();
toRemove.ForEach(id => sourceProductList.RemoveAll(p => p.ID == id));
于 2012-10-11T13:21:00.453 に答える
1

これは、名前でグループ化するのと同じくらい簡単で、グループに 1 つのアイテムしか存在しないものだけを取得する必要があります。

var filtered = list.GroupBy(i => i.Name)
      .Where(i => i.Count() == 1)
      .SelectMany(x => x)

実際の例: http://rextester.com/AUBOHU96105

于 2012-10-11T13:23:45.057 に答える