【问题标题】:Convert Java Lambda foreach on HashMap to a C# foreach on Dictionary将 HashMap 上的 Java Lambda foreach 转换为 Dictionary 上的 C# foreach
【发布时间】:2020-01-29 16:03:37
【问题描述】:

我这里的问题是将Java的HashMap foreach循环转换成C#的foreach...

 public static Map<Genre, List<Band>> PLAYER_ATTRIBUTE_HASHMAP = load();

上面我有 HashMap 的 Java 声明 - 我已经在 C# 中将它转换成这个:

public static Dictionary<Player, List<Attribute>> PLAYER_ATTRIBUTE_DICTIONARY = load();

目前它没有做任何异常,但我遇到了另一个问题,就是 lambda foreach 循环...

在 Java 中它看起来像:

PLAYER_ATTRIBUTE_HASHMAP.forEach((p, a) -> attributes.addAll(a));

它在 C# 中应该是什么样子?

它可以是字典上的正常foreach循环,但我无法理解这个东西..

我有另一个循环,我主要转换它,但与类中的 C# 方法同样存在类似问题。

    attributes.AddRange(PLAYER_ATTRIBUTE_DICTIONARY.Values.SelectMany(e => e));

        //PLAYER_ATTRIBUTE_DICTIONARY.forEach((p, a)->attributes.AddAll(a));
        List<Attribute> distinctAttributes = Attribute.distinctAttributesList(attributes);
        List<Player> players = new List<Player>(PLAYER_ATTRIBUTE_DICTIONARY.keySet()); // <--- problem with keyset

        PLAYER_ATTRIBUTE_DICTIONARY.forEach((p, a)-> { // <--- and there is also..
            List<Double> encodedPlayers = new List<Double>();
            List<Double> encodedAttributes = new List<Double>();
            foreach (Player player in players)
            {
                if (player.GetName().Equals(p.GetName()))
                {
                    encodedPlayers.Add(1.0);
                }
                else
                {
                    encodedPlayers.Add(0.0);
                }
            }
            foreach (Attribute distinctAttribute in distinctAttributes)
            {
                if (a.stream().anyMatch(attribute->distinctBand.getName().equals(attribute.getName()))) // <--- there is underline with stream and anyMatch
                {
                    encodedAttributes.Add(1.0);
                }
                else
                {
                    encodedAttributes.Add(0.0);
                }
            }
            dictionary.Add(encodedPlayers, encodedAttributes);
        });
        return dictionary;
    }

【问题讨论】:

  • 请不要使用最初从未提及的代码更新“初始”帖子的上下文......
  • @OusmaneD。无论哪种方式,它都是相同的方法,并且包含提到的标题问题,即 foreach with lambda..
  • @roxc:这并不完全正确。如何在字典上执行foreach 的基本问题非常简单。在您更新的代码中,您指出了 stream()anyMatch() 等方法调用的错误,这些错误与您最初提出的问题无关。

标签: java c# loops lambda foreach


【解决方案1】:

如果attributesforEach 之前是一个空列表,那么在C# 中执行起来会更好:

var attributes = PLAYER_ATTRIBUTE_DICTIONARY.SelectMany(e => e.Value).ToList();

如果没有,则使用AddRange

【讨论】:

    【解决方案2】:

    如果不知道 attributes 被声明为什么类型,很难确定。看起来你可能想要这样的东西:

    attributes.AddRange(PLAYER_ATTRIBUTE_DICTIONARY.Values.SelectMany(e => e));
    

    更新

    根据您更改后的问题,有几种方法可以查看此问题。要直接回答您提出的问题(即如何在 C# 中模拟 Java HashMap foreach),您可以替换为:

    PLAYER_ATTRIBUTE_DICTIONARY.forEach((p, a)-> {
    

    用这个:

    PLAYER_ATTRIBUTE_DICTIONARY.ToList().ForEach(kvp -> {
        var p = kvp.Key;
        var a = kvp.Value;
    

    您也可以只使用foreach 块:

    foreach(var keyValuePair in PLAYER_ATTRIBUTE_DICTIONARY)
    {
        var p = keyValuePair.Key;
        var a = keyValuePair.Value;
    

    但这实际上是一个 XY 问题的示例,您在问如何做某件特定的事情,因为您假设这是解决问题的方法。你正在做一堆非常奇怪的事情,比如用List&lt;Double&gt;s 作为键和值构建一个字典,而你编码的Double 值基本上是二进制的(一个或零)。这些可能实际上并不是解决您要解决的问题所必需的。如果您专注于您真正想从字典中取出哪些数据,我怀疑您可能会使用几个基本的 LINQ 语句获得一个更简单的解决方案。

    【讨论】:

    • List 属性 = new List();
    • 在属性类中我只有字段“名称”,它是字符串。
    猜你喜欢
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多