3 回答

TA貢獻1794條經驗 獲得超8個贊
小修正 - 當前實現的時間復雜度是 O(N*M),你能得到的最好的是 O(N+M)。
問題是如何有效地關聯這兩個集合。在 LINQ 中,這是通過連接實現的,對于這種一對多類型的關聯 -組連接。標準的等價物||將是兩個組連接(匹配集)結果的聯合。
談到可讀性、LINQ 和連接,最好的方法是使用 LINQ查詢語法(有些人也稱它為理解語法是有原因的)。
所以有問題的查詢可以有效地(并且希望可讀)重寫如下:
var invalidQuantityItems =
from returnItem in message.ItemsForReturn
join orderItem in message.OrderItems on returnItem.ItemNumber equals orderItem.ItemNumber
into matchingOrderItems1
join orderItem in message.OrderItems on returnItem.OrderItemId equals orderItem.OrderItemId
into matchingOrderItems2
let matchingOrderItemQuantity = matchingOrderItems1.Union(matchingOrderItems2)
.Sum(orderItem => orderItem.Quantity)
where matchingOrderItemQuantity < returnItem.Quantity
select returnItem;

TA貢獻1846條經驗 獲得超7個贊
我認為字典方法是最好的方法。
關于可讀性,我認為這應該不會太差:
var quantityByItemNumber = message.OrderItems.
Where(i => i.ItemNumber != null).
ToDictionary(
i => i.ItemNumber,
i => i.Quantity);
var quantityByOrderItemId = message.OrderItems.ToDictionary(
i => i.OrderItemId,
i => i.Quantity);
var invalidQuantityItems = message.ItemsForReturn.Where(returnItem =>
{
int matchingOrderItemQuantity;
var isNumberMatch = returnItem.ItemNumber != null) &&
quantityByItemNumber.TryGetValue(returnItem.ItemNumber, out matchingOrderItemQuantity);
if (!isNumberMatch)
quantityByOrderItemId.TryGetValue(returnItem.OrderItemId, out matchingOrderItemQuantity)
return matchingOrderItemQuantity < returnItem.Quantity;
});
事實上,我認為這更具可讀性,因為它不會錯誤地假裝有不止一個匹配OrderItem,必須對哪些數量求和。

TA貢獻1876條經驗 獲得超7個贊
就優化多個條件而言:
始終將最有可能結束評估的條件放在首位(您必須根據現有數據或您對系統的了解來確定這一點)。
如果一種情況比另一種情況更頻繁地發生的可能性不大,那么我們可以考慮評估本身。例如,如果
int
比較比比較快string
,則將int
比較放在第一位。
此外,您的代碼不需要單獨的行來獲取Sum
; 你可以用同一個表達式來做:
var invalidQuantityItems = message.ItemsForReturn.Where(returnItem =>
message.OrderItems
.Where(orderItem =>
orderItem.OrderItemId == returnItem.OrderItemId ||
orderItem.ItemNumber.Equals(returnItem.ItemNumber))
.Sum(orderItem => orderItem.Quantity) < returnItem.Quantity);
- 3 回答
- 0 關注
- 159 瀏覽
添加回答
舉報