如何过滤此特定列表?

时间:2018-06-20 21:12:00

标签: c# .net linq asp.net-web-api c#-4.0

我有以下界面。

public interface IProductPrices
    {
        int ProductId { get; set; }
        string ProductCode { get; set; }
        List<IProductPrice> Prices { get; set; }
    }

public interface IProductPrice
    {
        int ProductId { get; set; }
        string PriceKey { get; }
        double Price { get; set; }
        int Id { get; set; }
    }

代码段

//productPrices is of type IProductPrices
//temp is of type IProductPrice

........
var finalPriceList = new List<ABC.Model.ProductPrice>();
foreach (var item in productPrices)
    {
        foreach (var temp in item.Prices)
        {
            var prodPrice = new ABC.Model.ProductPrice()
            {
                Price = temp.Price,
                ProductCode = temp.ProductCode
            };
            finalPriceList.Add(prodPrice);
        }
    }
.....

上面的代码段中有一行

foreach (var temp in item.Prices)

仅当[item.Prices]等于[PriceKey]时,我才想从"ABC"中进行选择。如果[PriceKey]=="ABC"不存在,那么我想选择[Price]最低的项目。

如何实现?

2 个答案:

答案 0 :(得分:0)

使用我为提早退出Aggregate而编写的扩展方法,可以针对此问题编写特殊的MinBy变体。

这是我使用的AggregateUntil变体。也有While个变体和变体需要种子。

public static T AggregateUntil<T>(this IEnumerable<T> src, Func<T, T, T> accumFn, Predicate<T> endFn) {
    using (var e = src.GetEnumerator()) {
        T ans = default;
        if (e.MoveNext()) {
            ans = e.Current;
            while (!endFn(ans) && e.MoveNext())
                ans = accumFn(ans, e.Current);
        }
        return ans;
    }
}

现在您可以创建一个MinBy的变体,并尽早使用:

public static T MinByUnless<T, TKey>(this IEnumerable<T> src, Func<T, TKey> minFn, Func<T, bool> unlessFn ) =>
    src.AggregateUntil((a, b) => (Comparer<TKey>.Default.Compare(minFn(a), minFn(b)) < 0 && !unlessFn(b)) ? a : b, a => unlessFn(a));

使用它非常简单:

if (item.Prices.Any()) {
    var temp = item.Prices.MinByUnless(p => p.Price, p => p.PriceKey == "ABC");

答案 1 :(得分:0)

从您的商品中。价格中,您可以检查priceKey ==“ ABC”,否则像示例一样去获取扩展名为Min的最小值。

var finalPriceList = new List<ProductPrice>();
        var productPrices = new List<ProductPrice>();

        foreach (var item in productPrices)
        {
            foreach (var temp in item.Prices)
            {
                if (temp.PriceKey == "ABC")
                {
                    var prodPrice = new ProductPrice()
                    {
                        Price = temp.Price,
                        ProductCode = temp.ProductCode
                    };
                    finalPriceList.Add(prodPrice);
                }
                else
                {
                    int min = item.Prices.Min(entry => entry.Price);
                    var lowestPrice = item.Prices.Where(w => w.Price == min).Single();

                    var prodPrice = new ProductPrice()
                    {
                        Price = lowestPrice.Price,
                        ProductCode = lowestPrice.ProductCode
                    };
                    finalPriceList.Add(prodPrice);
                }
            }
        }