【问题标题】:C# - How to create a KeyValuePair with the result of two foreach loops?C# - 如何使用两个 foreach 循环的结果创建 KeyValuePair?
【发布时间】:2017-04-11 13:15:22
【问题描述】:

所以下面是我目前拥有的代码(它不起作用,因为最后一个块看到数组未定义,它是为了显示我想要做什么)

IEnumerable<string> sponsorshipQuery1 =
  from runner1 in venueQuery6.Descendants("Runner")
  where (int)runner1.Element("Sponsorship") > 0
  orderby (int)runner1.Element("Sponsorship") descending
  select runner1.Element("Firstname").Value;

IEnumerable<string> sponsorshipQuery2 =
  from runner1 in venueQuery6.Descendants("Runner")
  where (int)runner1.Element("Sponsorship") > 0
  orderby (int)runner1.Element("Sponsorship") descending
  select runner1.Element("Sponsorship").Value;

string[] nameArray;
string[] moneyArray;

foreach (string name in sponsorshipQuery1)
{
  nameArray = sponsorshipQuery1
    .OfType<object>()
    .Select(o => o.ToString()).ToArray();
}

foreach (string money in sponsorshipQuery2)
{
  moneyArray = sponsorshipQuery2
    .OfType<object>()
    .Select(o => o.ToString())
    .ToArray();
}

Console.WriteLine("All sponsorship money raised in descending order:");
for (int i = 0; i < nameArray.Length; i++)
{
  Console.WriteLine(nameArray[i] + " has raised £" + moneyArray[i]);
}

理想情况下,我希望能够在底部执行 for 循环。我猜想替换两个 foreach 循环并将它们设为 KeyValuePairs,但我不知道该怎么做。

我也是使用 Linq 查询的新手,所以我混合使用查询语法和 => 语法的原因是因为我学会了查询语法,但我也在尝试我在互联网上找到的代码.

【问题讨论】:

    标签: c# arrays linq loops key-value


    【解决方案1】:

    从您的示例代码中可以看出,您可以在一个查询中获取两个值,并将它们保存为匿名类型:

    var results = from runner1 in venueQuery6.Descendants("Runner")
                      where (int)runner1.Element("Sponsorship") > 0
                      orderby (int)runner1.Element("Sponsorship") descending
                      select new { 
                         Name = runner1.Element("Firstname").Value,
                         Amount = runner1.Element("Sponsorship").Value
                      };
    

    然后你可以遍历这些结果:

    foreach (var result in results)
    {
        Console.WriteLine(result.Name + " has raised £" + result.Amount);
    }
    

    【讨论】:

    • 我不知道您可以将select new 与大括号一起使用,据我所知,我只选择了一个值。这行得通,谢谢!
    • @TerminalGuy 它单个值,但该单个值可以包含多个 :)
    【解决方案2】:

    串联迭代两个序列的最高级别方法是使用Zip。要获得KeyValuePairs,我会使用

    sponsorshipQuery1.Zip(sponsorshipQuery2, (k, v) => new KeyValuePair<string, string>(k, v))
    

    虽然我可能根本不会使用 KeyValuePair,而是使用更具体的任务或匿名类型,除非我真正关心它作为键值对。

    迭代您已经介绍过的两个数组。要在两个无法(必然)被索引的IEnumerable&lt;T&gt; 上执行双foreach,需要将至少一个循环分解为其组件MoveNext()Current

    using (var en1 = sponsorshipQuery1.GetEnumerator())
    {
      foreach(var item2 in sponsorshipQuery2)
      {
        if (!en1.MoveNext())
        {
          break;
        }
        var item1 = en.Current;
        // Do something with the two items here. E.g.
      }
    }
    

    在您的特定示例中,因为您有一个共同的来源:

    from runner1 in venueQuery6.Descendants("Runner")
      where (int)runner1.Element("Sponsorship") > 0
      orderby (int)runner1.Element("Sponsorship") descending
    

    我只想select new KeyValuePair&lt;string, string&gt;(runner1.Element("Firstname").Value, runner.Element("Sponsorship").Value) 开始。

    【讨论】:

    • new KeyValuePair:你需要指定&lt;string, string&gt;(可悲)
    • 非常有趣...不得不说(可悲)当我有多个可枚举项手动枚举时,我通常在两者上都使用GetEnumerator()MoveNext...我从没想过混合foreach + MoveNext
    • 感谢您指出错误,@xanatos,是的,KeyValuePair 可以像 Tuple 那样使用 Create,但它被滥用为一个元组就足够了。
    • 谢谢!感谢您向我展示如何进行双重 foreach,我一直在努力弄清楚我之前应该如何做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 2015-08-12
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多