【发布时间】:2018-06-26 20:39:21
【问题描述】:
问题定义
我有一本<string, Tuple<List<T>, int>> 形式的字典。元组的 Item2 是 Item1 (List) 的字节大小。
我想根据每个字典的预定义最大大小将其分成多个字典,每个字典形式为 <string, List<T>>。
因此,我可能不得不分解一个值列表(List<T>;元组的第 1 项)(对应于单个 K-V 对)以进入多个字典。
到目前为止我已经尝试过什么
我想出了下面的代码,它以一种非常原始的方式进行分块 - 这仍然是 WIP,还没有完全工作。这里的逻辑是遍历每个 K-V 对并从列表中获取所有项目,直到我们达到预先定义的上述最大大小。
但在我进一步处理这段代码之前,我觉得必须有更好的方法来做到这一点。任何指针表示赞赏。
private async Task ChunkAsPerPayloadSizeAsync(IDictionary<string, Tuple<List<T>, int>> bufferSnapshot)
{
var dict = GetDictionary(bufferSnapshot); // This return the bufferSnapshot dictionary in the form <string, List<T>>
if (GetSizeOfDictionaryInBytes(dict) <= PayloadSizeInBytes)
{
await _makeRequest(dict); // This is a callback with the chunk in the correct size
}
else
{
var dict2 = new Dictionary<string, List<T>>();
var sizeInBytes = 0;
while (bufferSnapshot.Count > 0)
{
var itemId = bufferSnapshot.FirstOrDefault().Key;
if (bufferSnapshot.TryGetValue(itemId, out var data))
{
var thisSize = data.Item2 + FindSize<string>.SizeOf(itemId);
if (sizeInBytes + thisSize <= PayloadSizeInBytes)
{
sizeInBytes += thisSize;
dict2.Add(itemId, data.Item1);
bufferSnapshot.Remove(itemId);
}
else
{
// now we have to chunk the values
var sizeInBytesOfValuesList = data.Item2;
var valuesCount = data.Item1.Count;
var sizePerValue = sizeInBytesOfValuesList / valuesCount;
var spaceAvailable = RequestPayloadSizeInBytes - sizeInBytes - FindSize<string>.SizeOf(itemId);
var numberOfValuesToTake = spaceAvailable / sizePerValue;
if (numberOfValuesToTake > 0)
{
if (numberOfValuesToTake < data.Item1.Count)
{
var items = data.Item1.Take(numberOfValuesToTake);
data.Item1.RemoveRange(0, numberOfValuesToTake);
dict2.Add(itemId, items.ToList());
}
else
{
dict2.Add(itemId, data.Item1);
}
}
}
}
}
}
}
【问题讨论】:
-
如果你已经有了大小,你可以使用
Where根据元组报告的大小过滤字典,然后使用Except得到其余的,然后在结果上简单地调用ToDictionary.我不知道你在所有这些代码中究竟在做什么什么,因为我不敢直视它,以免我掉进兔子洞。 -
我不太清楚。你想要一份清单吗?每个元组都有一个最大大小的元素?您应该提供更多信息
-
这是knapsack-type problem,您是在尝试将尽可能多的项目塞入每个存储桶中,还是可以只遍历项目直到找到一个超过 maxSize 的项目,然后从下一个桶开始?
-
@itsme86,是的,这是一个背包式问题。更像是 2 个嵌套的背包问题。
-
为什么投反对票?我有一个问题陈述,我自己努力的代码示例,并且明确指出我正在寻找指针,而不是勺子喂养的解决方案。上面评论中指向背包问题的指针实际上有所帮助。
标签: c# .net dictionary chunking