How can I get the the half of elements of a list?
The problem is: I got a list of elements and then I use group by. I need to get another list where contains the half of elements from each group by.
How can I do that? I'm using LINQ.
UPDATE:
This is the first list that I get.
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(),
};
That's the original which I'm using. From that one, I only want to get the half of problems from each OBJECTIVEID.
If in the enummerable I have 2 elements of the same objectiveID, I must get only one. If I go开发者_高级运维t one problem, I must get only one, If I have 5 I'd have 2 or 3.
I'm not sure what you're asking -- are you trying to get individual elements from each group into another list? If so, SelectMany is probably what you're looking for.
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();
Alternatively:
var evens = evensAndOdds.Single(g => g.Key == 0).ToList();
Response to Edit
There's an overload of Select that also includes an integer index -- you can use this to filter out all the odd or even items to get half of the set.
You could change it to something like
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()
I'm beginning to think I don't understand the question. If the problem is that you have data like
condition1: objectiveID = 2 problemID = 100
condition2: objectiveID = 2 problemID = 101
and you don't want two different problemIDs for the same objectiveID, you can use GroupBy / SelectMany / Take to narrow down to only one problem per objectiveID
xdoc.Descendants("Condition")
.GroupBy(c => c.Attribute("objectiveID").value)
.SelectMany(group => group.Take(1))
For an arbitrary IEnumerable
you can get an alternating split into two lists using:-
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);
精彩评论