C# рассчитать общий вес - PullRequest
0 голосов
/ 13 июля 2020

У меня два класса, как показано ниже. Я получаю список продуктов «ProductBooleans» вместе с флагом категории, если они в него вписываются. Я также получаю вес для каждой категории ProductWeight. Мне нужно найти общий вес для каждой категории.

public class ProductBooleans
{
    public int Prodid;
    public int Cat1;
    public int Cat2;
    public int Cat3;
}

public class ProductWeight
{
    public string Cat;
    public int Wt;
}

Мне нужно рассчитать общий вес для каждого продукта в корзине и вернуть dict

ProductBoolean

var pbs = new List<ProductBooleans>()
{
    new ProductBooleans() { Prodid = 333, Cat1 = 1, Cat2 = 0, Cat3 = 1, },
    new ProductBooleans() { Prodid = 444, Cat1 = 1, Cat2 = 1, Cat3 = 0, },
};

ProductWeight

var pws = new List<ProductWeight>()
{
    new ProductWeight() { Cat = "Cat1", Wt = 10, },
    new ProductWeight() { Cat = "Cat2", Wt = 20, },
    new ProductWeight() { Cat = "Cat3", Wt = 30, },
};

Результат должен быть

Prodid | totalWt
333        40
444        30

ПРИМЕЧАНИЕ. В настоящее время я использую отражение для решения этой проблемы, но я думаю, что должен быть гораздо более простой способ добиться этого. Есть ли библиотека для этого или более простой способ?

Ответы [ 2 ]

0 голосов
/ 13 июля 2020
        var _categoryDic = new Dictionary<Category, bool>();
        _categoryDic.Add(new Category() { CategoryName = "cate1", CatId = 1 }, true);
        _categoryDic.Add(new Category() { CategoryName = "cate2", CatId = 2 }, false);
        _categoryDic.Add(new Category() { CategoryName = "cate3", CatId = 3 }, true);
        productBooleans.Add(new ProductBooleans()
        {
            prodid = 333
                        ,
            categoryDic = _categoryDic
        });

        var _categoryDic2 = new Dictionary<Category, bool>();
        _categoryDic2.Add(new Category() { CategoryName = "cate1", CatId = 1 }, true);
        _categoryDic2.Add(new Category() { CategoryName = "cate2", CatId = 2 }, true);
        _categoryDic2.Add(new Category() { CategoryName = "cate3", CatId = 3 }, false);
        productBooleans.Add(new ProductBooleans()
        {
            prodid = 444
                        ,
            categoryDic = _categoryDic2
        });

        List<ProductWeight> productWeights = new List<ProductWeight>();

        productWeights.Add(new ProductWeight() { category = new Category() { CategoryName = "cate1", CatId = 1 }, weight = 10 });
        productWeights.Add(new ProductWeight() { category = new Category() { CategoryName = "cate2", CatId = 2 }, weight = 20 });
        productWeights.Add(new ProductWeight() { category = new Category() { CategoryName = "cate3", CatId = 3 }, weight = 30 });

        var _prodBool =productBooleans.Select(i => new {
                                                                    prod_id = i.prodid
                                                                     ,
            categoryList = i.categoryDic
                            .Where(j => j.Value)
                            .Select(j => j.Key)
                            .ToList<Category>()
        }).ToList();
        Dictionary<int, int> resultList=new Dictionary<int, int>();
        foreach (var item in _prodBool)
        {
            int itemweight = 0;
            foreach (var pw in productWeights)
            {
                itemweight += (item.categoryList.Where(i => i.CatId == pw.category.CatId).Any()) ? pw.weight : 0;
            }
            resultList.Add(item.prod_id, itemweight);
        }
        return resultList;
0 голосов
/ 13 июля 2020

Похоже, это сработало для меня:

var query =
    from pb in pbs
    let totalWt =
    (
        from x in new (string Cat, int Wt)[]
        {
            ("Cat1", pb.Cat1),
            ("Cat2", pb.Cat2),
            ("Cat3", pb.Cat3),
        }
        join pw in pws on x.Cat equals pw.Cat
        select x.Wt * pw.Wt
    ).Sum()
    select new
    {
        pb.Prodid,
        totalWt
    };

Это дает мне:

результат

Вот версия, в которой используется отражение:

(string Cat, int Wt)[] GetValues(ProductBooleans pb) =>
    typeof(ProductBooleans)
        .GetFields()
        .Where(p => p.Name.StartsWith("Cat"))
        .Where(p => p.FieldType == typeof(int))
        .Select(p => (p.Name, (int)p.GetValue(pbs[0])))
        .ToArray();

var query =
    from pb in pbs
    let totalWt =
    (
        from x in GetValues(pb)
        join pw in pws on x.Cat equals pw.Cat
        select x.Wt * pw.Wt
    ).Sum()
    select new
    {
        pb.Prodid,
        totalWt
    };

Очевидно, измените .GetFields() на .GetProperties(), если это необходимо.

...