Выполните поиск между C# Lists и верните соответствие, где значение является минимальным - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть два списка:

var qtys = new List<InventoryQuantity>()
{
    new InventoryQuantity() { WarehouseId = 1, QuantityInWarehouse = 0 },
    new InventoryQuantity() { WarehouseId = 2, QuantityInWarehouse = 452 },
    new InventoryQuantity() { WarehouseId = 3, QuantityInWarehouse = 184 },
    new InventoryQuantity() { WarehouseId = 4, QuantityInWarehouse = 328 },
    new InventoryQuantity() { WarehouseId = 5, QuantityInWarehouse = 0 },
};

var times = new List<WarehouseTransitTime>()
{
    new WarehouseTransitTime() { WarehouseId = 1, TransitDays = 1 },
    new WarehouseTransitTime() { WarehouseId = 2, TransitDays = 4 },
    new WarehouseTransitTime() { WarehouseId = 3, TransitDays = 2 },
    new WarehouseTransitTime() { WarehouseId = 4, TransitDays = 3 },
    new WarehouseTransitTime() { WarehouseId = 5, TransitDays = 5 },
};

class InventoryQuantity
{
    public int WarehouseId { get; set; }
    public int QuantityInWarehouse { get; set; }
}

class WarehouseTransitTime
{
    public int WarehouseId { get; set; }
    public int TransitDays { get; set; }
}

Мне нужно вернуть WarehouseId из qtys, где Количество> 0 и WarehouseId равны минимальным транзитным дням WarehouseId в разах.

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

    public int NearestWarehouse()
    {
        var withQty = qtys.Where(i => i.QuantityInWarehouse > 0);
        var orderedTransit = times.OrderBy(tt => tt.TransitDays).ToList();
        //loop and compare
    }

Пример данных:

qtys

WarehouseId | Quantity
1           | 0
2           | 452
3           | 184
4           | 328
5           | 0

times

WarehouseId | TransitTime
1           | 1
2           | 4
3           | 2
4           | 3
5           | 5

Ожидаемый результат будет 3, потому что склад 3 имеет запас и самое короткое время транзита (2)

Ответы [ 4 ]

2 голосов
/ 18 февраля 2020

Мне кажется, что самый чистый и простой запрос такой:

var query =
    from q in qtys
    where q.QuantityInWarehouse > 0
    join t in times on q.WarehouseId equals t.WarehouseId
    orderby t.TransitDays
    select q.WarehouseId;

var warehouseId = query.FirstOrDefault();

Это дает мне 3.

2 голосов
/ 17 февраля 2020

Требуется групповое объединение :

Функциональный синтаксис

var query1 = qtys.Where(q => q.QuantityInWarehouse > 0)
                 .GroupJoin(times, q => q.WarehouseId, t => t.WarehouseId, (q, t) => new { q.WarehouseId, TransitDays = t.DefaultIfEmpty().Min(grp => grp?.TransitDays) })
                 .OrderBy(g => g.TransitDays)
                 .FirstOrDefault();

Синтаксис запроса

var query2 = from q in qtys
             join t in times on q.WarehouseId equals t.WarehouseId into grp
             where q.QuantityInWarehouse > 0
             select new
             {
                 q.WarehouseId,
                 TransitDays = grp.DefaultIfEmpty().Min(g => g?.TransitDays)
             };

var result = query2.OrderBy(g => g.TransitDays)
                   .FirstOrDefault();

Групповое объединение объединит два списка вместе по соответствующим им ключам - подобно соединению с базой данных - и связанные значения для этих ключей будут сгруппированы в перечислимое. Из этого перечисления вы можете получить минимальное значение, которое вас волнует, в данном случае TransitDays.

В синтаксисе запроса нет эквивалента «first или default». Самый простой подход - просто применить те же OrderBy и FirstOrDefault к переменной запроса, как показано выше.

1 голос
/ 17 февраля 2020

Вы можете сделать это так ..

   var withQty = (from q in qtys
                       join t in times on q.WarehouseId equals t.WarehouseId
                       where q.QuantityInWarehouse > 0
                       select new { q.WarehouseId, t.TransitDays })
                       .OrderBy(item => item.TransitDays).FirstOrDefault();


   return withQty?.WarehouseId ?? 0;
1 голос
/ 17 февраля 2020

Ну, вы упомянули отношение AND между ними, верно?

Я думал о базах данных с помощью forignkey ... но Linq prety много делает, если ваши списки не слишком большие:

keys = qtys.Where(i => i.QuantityInWarehouse > 0).Select(i => i.WarehouseId).ToList();
// get the smallest not a list
var result = times.Where(tt => keys.Contains(tt.wharehouseId)).orderby(tt => tt.Transitdays).FirstOrDefault();

В противном случае вы могли бы иметь Dictionary с ID в качестве ключа ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...