在批量轉換串列時,yield return 跳過已檢入 if 條件但由于大小限制未添加到存盤桶的物件。
訊息總數:4
第一個桶數:2
第二個桶數:1
訊息串列中的第三條訊息被跳過。
在這里,我正在創建大小為 250kb 的存盤桶。還有其他方法可以保存正確的狀態還是需要使用 for 回圈?
public static IEnumerable<IEnumerable<Message>> GetBatchSize(IList<Message> source)
{
List<Message> bucket = null;
long size = 0;
foreach (var item in source)
{
if (bucket == null)
{
bucket = new List<Message>();
}
size = size item.Size;
if (250 - (size / 1024) >= item.Size / 1024)
{
bucket.Add(item);
continue;
}
yield return bucket;
bucket = new List<Message>();
size = 0;
}
if (bucket?.Count > 0 && size<250)
{
yield return bucket;
}
}
uj5u.com熱心網友回復:
您可以將專案添加到收益回傳后新創建的串列中:
foreach (var item in source)
{
// omitted for brevity
yield return bucket;
bucket = new List<Message> { item };
size = item.Size;
}
uj5u.com熱心網友回復:
(假設沒有單個訊息的大小大于桶大小)
首先,當當前桶不能包含當前訊息時,您應該將訊息放入下一個桶中,而不是將其扔掉。因此,在foreach回圈中回傳 yield 之后,您應該執行以下操作:
bucket = new() { item };
^^^^^^^^
此外,您將專案添加到存盤桶的條件不正確。它“雙重計算”當前專案的大小。注意size此時已經item.Size添加進去了!此外,在此處使用除法將丟棄余數,這會導致在以下情況下產生不正確的結果:
GetBatchSize(new List<Message> {
new Message { Size = 250 * 1024 - 1 },
new Message { Size = 1 },
new Message { Size = 1 },
});
不是除法,而是乘法:
if (size <= 250 * 1024)
{
bucket.Add(item);
continue;
}
另外,我不確定最后一次size < 250檢查的目的是什么。您可能的意思是size < 250 * 1024,但由于回圈的不變性,這應該總是正確的,所以您可以洗掉它:
if (bucket?.Count > 0)
{
yield return bucket;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/378935.html
上一篇:如何計算給定坐標(x,y)使用一步/兩步向下或向左到達(0.0)的路徑數?在C
下一篇:如何遞回遍歷陣列并替換某些值?
