在O(n)时间内更新C#键控集合中的所有值?

Ael*_*ian 5 .net c# collections

这是我在C#中一次又一次遇到的问题,但还没有找到一般解决方案.在C++/STL中,可以使用迭代器在O(n)时间内更新映射中的所有值,而无需使用键来访问每个元素.有没有办法获得与任何C#集合类似的行为,如SortedList,SortedDictionary?

我可以做点什么

foreach (int key in list.Keys)
{
    list[key] *= 3;
}
Run Code Online (Sandbox Code Playgroud)

但是这需要O(n*log(n))作为搜索每个元素使用key取log(n).

只是为了提出一个想法,我正在寻找以下内容:

SortedList<int, double> list = new SortedList<int,double>();

// Add few values fist

// E.g. first try ...
IList<double> values = list.Values;
for (int i = 0; i < values.Count; i++)
{
    values[i] *= 3;
}

// E.g. second try
foreach (KeyValuePair<int, double> kv in list)
{
    kv.Value *= 3;
}
Run Code Online (Sandbox Code Playgroud)

由于List已经排序,因此应该可以遍历它同时更新值(而不是键).从实现的角度来看,它看起来并不存在问题,但由于某种原因,似乎没有提供功能.

此外,这不是一个简单的情况,因为可以使用相同的方法从已知位置迭代到该范围内的另一个修改值.

有没有办法在C#中使用.NET中的任何键控集合而不使用第三方库?

谢谢

占道

Kna*_*ģis 3

最简单的解决方案是将值包装在引用类型中。

class WrappedInt { public int Value; }
Dictionary<TKey, WrappedInt> dictionary = ...;
foreach (var wrappedVal in dictionary.Values)
{
    wrappedVal.Value *= 3;
}
// or 
foreach (var wrappedVal in dictionary)
{
    wrappedVal.Value.Value *= 3;
}
Run Code Online (Sandbox Code Playgroud)

这种方法适用于任何集合(列表或字典)。是少数几个在没有包装器的情况下通过设计实现此目的的集合之一LinkedList

当然,如果您有一个非常具体的集合(由某些外部组件创建),您始终可以回退到使用反射并直接在底层存储中更改值。