Корзина с фруктами, как использовать Linq для просмотра с корзины или с точки зрения фруктов? - PullRequest
2 голосов
/ 31 августа 2009

Вопрос связан с финансовыми продуктами, процентными ставками и двумя свойствами, которые определяют, какой процент имеет определенный продукт. Но я думаю, что фрукты и корзины легче визуализировать для этого.

Во-первых, у нас есть фрукты. Плод может иметь определенный размер (маленький, средний, большой) и цвет (красный, зеленый, синий). Это будут два разных перечисления. Корзины будут содержать все виды фруктов, но нет двух одинаковых по цвету и форме. Но каждая возможная комбинация будет в корзине. Поскольку у нас есть три размера и три цвета, в каждой корзине будет 9 кусочков фруктов. Если бы у нас было 4 цвета, мы бы получили 12 штук.

Мы храним информацию о корзине для каждой корзины. Каждая корзина имеет словарь <{Size, Color}, Fruit>, который определяет все кусочки фруктов в корзине. Однако этот словарь может быть не полностью полным, и в этом случае все остальные комбинации являются яблоками. Словарь содержит только фрукты другого вида. (Хотя они тоже могут содержать яблоки.) Рядом с яблоками у нас также есть груши и бананы. Да, они могут быть красными, но мне было бы интересно, какая краска использовалась, чтобы сделать их красными. Помните, это просто для визуализации проблемы. : -)

В любом случае, теперь у меня есть список корзин с корзиной фруктов. Яблоки по умолчанию, груши или бананы, если они в словаре. Но мне нужно смотреть на информацию под другим углом.

Мне нужно преобразовать эту структуру в список фруктов и по корзинам фруктов, где их можно найти, плюс размеры и цвета конкретного фрукта. Таким образом, бананы находятся в корзине 1 ({маленький, желтый}, {маленький, красный}, {средний, красный}), корзина 3 (...), корзина 4, 8 и 10. То же самое с грушами, но я могу ' в корзине 1 желтая груша, так как она уже определена для банана.

У меня есть большое преимущество: ни одна из этих структур четко не определена! Тем не менее, мне нужно представление корзины как способ предоставления информации для процесса преобразования. И мне нужно представление «Фрукты» для дальнейших вычислений, так как мне нужно сделать дополнительную математику, основанную только на самих фруктах, а не на их размере или цвете или корзине, из которой они происходят ...

Итак, есть ли хорошие предложения для структуры до и после преобразования, и как сделать само преобразование, используя Linq в C #? <ч /> В действительности корзины - это продукты. Размер и цвет - меньшие различия на продуктах. Плоды - это процентные ставки, и мне нужна только эта ставка для математики. Группируя продукт по его процентной ставке, я могу сократить количество вычислений до нескольких. Мы имеем дело с более чем 1600 продуктами на каждый продукт (около 10х10) в 100 различных вариантах, что составляет 160 000 процентных ставок. Сами ставки, как правило, составляют от 3 до 7,5% и округляются до 1/20 процента. Таким образом, около 90 различных ставок приводят к 90 расчетам вместо 160 000 вычислений ...

И мне нужно убедить руководство сделать этот шаг, потому что они боятся, что это много работы, станет нечитабельным или его будет сложно поддерживать.


На основе процентной ставки вы можете рассчитать, сколько человек может одолжить, исходя из того, сколько он готов потратить в месяц на продукт с определенными условиями. Эта оптимизация позволит мне намного быстрее сравнивать разные продукты. Жаль, что я первый в компании, кто заметил эту интересную оптимизацию! : -)

1 Ответ

2 голосов
/ 01 сентября 2009

Ну, как только я начал, мне пришлось написать весь код. Возможно, это не решит твою основную проблему, но я думаю, что это прибивает вещь корзины с фруктами.

public enum FruitSize{Small, Medium, Large}
public enum FruitColor {Red, Green, Blue}

  // immutable struct is important for use as dictionary keys
public struct FruitDescription
{
    readonly FruitSize _size;
    public FruitSize Size {get{return _size;}}
    readonly FruitColor _color;
    public FruitColor Color { get { return _color; } }
    public FruitDescription(FruitSize size, FruitColor color)
    {
        _size = size;
        _color = color;
    }
}
    //abstract parent class ...
public abstract class Fruit
{ public FruitDescription Description {get;set;} }
    //... and children
public class Apple : Fruit{}
public class Banana : Fruit{}
public class Pear : Fruit{}

public class Basket
{
    private Dictionary<FruitDescription, Fruit> internalFruits =
        new Dictionary<FruitDescription, Fruit>();

    public void AddFruit(Fruit addme)
    {
        internalFruits[addme.Description] = addme;
    }

    public IEnumerable<FruitDescription> AllDescriptions()
    {
        foreach (FruitSize size in Enum.GetValues(typeof(FruitSize)))
        {
            foreach (FruitColor color in Enum.GetValues(typeof(FruitColor)))
            {
                FruitDescription desc = new FruitDescription(size, color);
                yield return desc;
            }
        }
    }

    public Apple GetDefaultApple(FruitDescription desc)
    {
        return new Apple() { Description = desc };
    }

    public IEnumerable<Fruit> GetFruits()
    {
        IEnumerable<Fruit> result = AllDescriptions()
            .Select(desc =>
              internalFruits.ContainsKey(desc) ?
              internalFruits[desc] :
              GetDefaultApple(desc));
        return result;
    }
}

public class Pair<T, U>
{
    public T First { get; set; }
    public U Second { get; set; }
}

public class TestClass
{
    public static void Test()
    {
        Basket b1 = new Basket();
        b1.AddFruit(new Banana() { Description =
            new FruitDescription(FruitSize.Medium, FruitColor.Blue) });
        b1.AddFruit(new Banana() { Description =
            new FruitDescription(FruitSize.Medium, FruitColor.Green) });

        Basket b2 = new Basket();
        b2.AddFruit(new Pear() { Description =
            new FruitDescription(FruitSize.Medium, FruitColor.Green) });

        List<Basket> source = new List<Basket>();
        source.Add(b1);
        source.Add(b2);

        //the main event - a query.
        List<Pair<Fruit, Basket>> result =
        (
          from basket in source
          from fruit in basket.GetFruits()
          select new Pair<Fruit, Basket>()
          { First = fruit, Second = basket }
        ).ToList();

        //a second results structure for fun
        ILookup<Type, Basket> resultByType = result.ToLookup
        (
            p => p.First.GetType(),
            p => p.Second
        );

        Console.WriteLine("Number of fruit: {0}",
            result.Count);
        Console.WriteLine("Number of apples: {0}",
            resultByType[typeof(Apple)].Count());
        Console.WriteLine("Number of baskets with apples: {0}",
            resultByType[typeof(Apple)].Distinct().Count());
        Console.WriteLine("Number of bananas: {0}",
            resultByType[typeof(Banana)].Count());
        Console.WriteLine("Number of baskets with bananas: {0}",
            resultByType[typeof(Banana)].Distinct().Count());
    }

}

С этими результатами:

Number of fruit: 18
Number of apples: 15
Number of baskets with apples: 2
Number of bananas: 2
Number of baskets with bananas: 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...