如何获得列表中一半的元素?

时间:2011-08-30 22:53:50

标签: c# linq list

问题是:我有一个元素列表,然后我使用group by。我需要获得另一个列表,其中包含每个组中的一半元素。

我该怎么做?我正在使用LINQ。

更新:

这是我得到的第一个清单。

        XDocument xdoc = XDocument.Load(path);
        var conditions = from c in xdoc.Descendants("Condition")
                         select new
                         {
                             ObjectiveID = (int)c.Attribute("ObjectiveID"),
                             TypeID = (int)c.Attribute("TypeID"),
                             ProblemID = (int)c.Attribute("ProblemID"),
                             Ranges = (from r in c.Descendants("Range")
                                       select new
                                       {
                                           Decimals = (int)r.Attribute("Decimals"),
                                           Min = (decimal)r.Attribute("Min"),
                                           Max = (decimal)r.Attribute("Max")
                                       }).ToArray(),
                         };

这是我正在使用的原件。从那一点开始,我只想从每个OBJECTIVEID中获得一半的问题。

如果在无法忍受的情况下,我有2个相同objectiveID的元素,那么我必须只有一个。如果我遇到一个问题,我必须只得到一个问题,如果我有5个问题,我会得到2个或3个。

2 个答案:

答案 0 :(得分:5)

我不确定你在问什么 - 你是不是想把每个组中的个别元素放到另一个列表中?如果是这样,SelectMany可能正是您所寻找的。

var numbers = new[] { 1,2,3,4,5,6,7,8,9 };
var evensAndOdds = numbers.GroupBy(x => x % 2);
var evens = evensAndOdds.Where(g => g.Key == 0).SelectMany(g => g).ToList();
var odds =  evensAndOdds.Where(g => g.Key == 1).SelectMany(g => g).ToList();

可替换地:

var evens = evensAndOdds.Single(g => g.Key == 0).ToList();

<小时/> 对编辑的响应

Select的重载也包含整数索引 - 您可以使用它来过滤掉所有奇数或偶数项以获得一半的设置。

您可以将其更改为

Ranges = c.Descendants("Range")
          .Select((range,i) => new { range, i })
          .Where(pair => pair.i % 2 == 0) // select only even items
          .Select(pair => new {
               Decimals = (int)pair.range.Attribute("Decimals"),
               ... etc...
          })
          .ToArray()

<小时/> 我开始认为我不明白这个问题。如果问题是你有像

这样的数据
condition1: objectiveID = 2 problemID = 100
condition2: objectiveID = 2 problemID = 101

并且您不希望同一个objectiveID有两个不同的problemID,您可以使用GroupBy / SelectMany / Take缩小到每个objectiveID只有一个问题

xdoc.Descendants("Condition")
    .GroupBy(c => c.Attribute("objectiveID").value)
    .SelectMany(group => group.Take(1))

答案 1 :(得分:0)

对于任意IEnumerable,您可以使用以下方法将交替拆分为两个列表: -

var oneHalf = list.Select((x, i) => new {x, i}).Where(t => t.i%2 == 0).Select(t =>t.x);
var otherHalf = list.Select((x, i) => new {x, i}).Where(t => t.i%2 != 0).Select(t =>t.x);