在C#中的等效Map.Compute功能。

huangapple go评论79阅读模式
英文:

Equivalent Map.Compute in C#

问题

Sure, here's the translated code:

Dictionary<int, int> map = new Dictionary<int, int>();
foreach (int i in elements)
    map[i] = map.ContainsKey(i) ? map[i] + 1 : 1;

Let me know if you need further assistance!

英文:

I am trying to convert some code from java to C# but I´m stuck with this:

Map&lt;Integer, Integer&gt; map = new HashMap&lt;&gt;(); // converted to Dictionary&lt;int, int&gt;
for (int i : elements)//converted to  foreach (int i in elements)
    map.compute(i, (k, v) -&gt; (v == null) ? 1 : v+1)

What is the equivalent If I'm doing it with a dictionary in C#?

答案1

得分: 1

我不知道存在确切的等同物,所以可能需要在某种程度上自己实现它。如果你正在寻找一个看起来和感觉相同的解决方案,你可以为 Dictionary<K,V> 添加一个扩展

这些语言之间有足够的差异,需要一些手工操作,但要抓住要点,这应该足够作为一个起点。

在C#的Dictionary上不存在Compute,所以你可以添加它。理想情况下,对于一个“等效”的版本,你会希望确保它涵盖了所有原始版本的情况,而不仅仅是这个特定的情况(依我之见)。我不敢断言以下代码完全等同,但你可以通过调查你的Java版本中compute的源代码来确保你的版本与原始版本相符(这是我在查看HashMap时得出的,可能不准确)。

// 你可以轻松地添加到Dictionary<K, V>的实现中;太棒了!
public static class DictExtensions
{
    public static V Compute<K, V>(this Dictionary<K, V> dict, K key, Func<K, V, V> func)
    {
        // 如果没有提供func,抛出异常。
        if (func == null) throw new ArgumentNullException(nameof(func));
        // 如果没有映射,返回null。
        if (!dict.TryGetValue(key, out var value)) return default;
        // 从func获取新值。
        var result = func(key, value);
        if (result == null)
        {
            // 如果映射存在但func => null,
            // 删除映射并返回null。
            dict.Remove(key);
            return default;
        }
        // 映射存在,func返回非null值。
        // 设置新值并返回。
        dict[key] = result;
        return result;
    }
}

然后,在将正确的using语句添加到你想要在其中使用Compute的代码之后,可以像你期望的那样使用它:map.Compute(i, (k, v) => (v == null) ? 1 : v + 1);

英文:

I don't know of an exact equivalent that exists so it may come down to implementing it yourself to some degree. If you're looking for a solution that looks and feels the same, you can add an extension to Dictionary&lt;K,V&gt;.

There's sufficient differences between these languages to require a bit of hand waiving but, to get to the gist of it, this should suffice as a starting point.

Compute doesn't exist on the C# Dictionary so you can add it. Ideally, for an "equivalent", you'd want to ensure it covers all the cases as the original, not just this particular case (IMHO). I don't claim that the following does but you can ensure yours does by investigating the source code for compute in your Java version. (this is what I came up with looking over HashMap; I could be off).

// You can easily add to the Dictionary&lt;K, V&gt; implementation; SWEET!
public static class DictExtensions
{
    public static V Compute&lt;K, V&gt;(this Dictionary&lt;K, V&gt; dict, K key, Func&lt;K, V, V&gt; func) 
    {
        // if no func given, throw.
        if (func == null) throw new ArgumentNullException(nameof(func));
        // if no mapping, return null.
        if (!dict.TryGetValue(key, out var value)) return default;
        // get the new value from func.
        var result = func(key, value);
        if (result == null)
        {
            // if the mapping exists but func =&gt; null,
            // remove the mapping and return null.
            dict.Remove(key);
            return default;
        }
        // mapping exists and func returned a non-null value.
        // set and return the new value
        dict[key] = result;
        return result;
    }
}

Then, after adding a correct using statement to the code you'd like to use Compute in, use it like you expect: map.Compute(i, (k, v) =&gt; (v == null) ? 1 : v + 1);

huangapple
  • 本文由 发表于 2020年8月19日 05:38:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63476986.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定