【问题标题】:Getting distinct values from linq to xml query从 linq 到 xml 查询获取不同的值
【发布时间】:2013-08-19 07:34:00
【问题描述】:

我正在获取一个 csv 文件并将其转换为 XML,并且效果很好。

XML 看起来像这样

<Root>
  <Player index="0">
    <Rank>
      <Level> A</Level>
      <Class>   1</Class>
    </Rank>
    <TopScores>
      <Lives>      1.0</Lives>
      <Kills>      0.0</Kills>
      <Time> 9:59:55</Time>
    </TopScores>
  </Player>
  <Player index="1">
    <Rank>
      <Level> A</Level>
      <Class>   2</Class>
    </Rank>
    <TopScores>
      <Lives>      1.2</Lives>
      <Kills>      0.0</Kills>
      <Time> 9:59:59</Time>
    </TopScores>
  </Player>
  <Player index="2">
    <Rank>
      <Level> A</Level>
      <Class>   3</Class>
    </Rank>
    <TopScores>
      <Lives>      1.2</Lives>
      <Kills>      0.0</Kills>
      <Time>10: 0: 3</Time>
    </TopScores>
  </Lives>
  <Player index="3">
    <Rank>
      <Level> A</Level>
      <Class>   1</Class>
    </Rank>
    <TopScores>
      <Lives>      0.9</Lives>
      <Kills>      0.0</Kills>
      <Time>10: 0: 8</Time>
    </TopScores>
  </Player>
</Root>

如您所见,有一个重复的 Rank(1 级,0 级)。

我可以通过以下查询获得重复的数量:

//The query below will return the duplicates so we can report the identities
//and the count of the number of duplicates.
var duplicates = playerData.Descendants("Rank")
                  .GroupBy(c => c.ToString())
                  .Where(g => g.Count() > 1)
                  .Select(g => g.First().Value);

我想获取所有“排名”值的完整玩家数据,但是如果存在重复的“排名”值,我想获取最后一次出现的值。所以对于上面的 XML 数据,我应该只返回三组 Player 数据,当有重复时,它应该是最晚时间或 id 的。

为此我已经尝试过:

var uPlays = playerData.Descendants("Player").Descendants("Rank")
                       .GroupBy(z => z.ToString())
                       .Select(b => b.Ancestors().First());

这为我提供了排名唯一值的所有玩家数据,但当然它为我提供了遇到的第一个实例。我以为我只需将 .First() 更改为 .Last() 但这只会让我重复第一个值的三倍。

【问题讨论】:

    标签: xml linq lambda no-duplicates


    【解决方案1】:

    我会尝试这样的事情

    var uPlays = playerData.Root.Elements("Player")
                          .GroupBy(c => c.Element("Rank").ToString())
                          .Select(g => g.Last());
    

    或使用您的代码

    var uPlays = playerData.Descendants("Player")
                           .Descendants("Rank")
                           .GroupBy(z => z.ToString())
                           .Select(b => b.Last().Parent);
    

    【讨论】:

    • 感谢 Raphael,我正在使用 XElement,所以我认为这就是您的第一个建议对我不起作用的原因。你的第二个建议就像一个魅力!当然,我将 .First 更改为 .Last ,这很有效。我希望我能更好地理解发生了什么。有谁有最喜欢的参考资料吗?
    猜你喜欢
    • 2014-02-08
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多