2011-08-30 2 views
2

Le problème est: J'ai une liste d'éléments et ensuite j'utilise le groupe par. J'ai besoin d'une autre liste contenant la moitié des éléments de chaque groupe.Comment puis-je obtenir la moitié des éléments d'une liste?

Comment puis-je faire cela? J'utilise LINQ.

MISE À JOUR:

Voici la première liste que je reçois.

 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(), 
         }; 

C'est l'original que j'utilise. De celui-là, je veux seulement obtenir la moitié des problèmes de chaque OBJECTIVEID.

Si dans l'énumérable j'ai 2 éléments du même objectifID, je dois en obtenir un seul. Si j'ai un problème, je dois en obtenir un seul. Si j'en ai 5, j'en aurais 2 ou 3.

+0

Utilisez sauter et prendre –

+0

s'il vous plaît montrer un code source ... – Yahia

+0

informations mises à jour – Darf

Répondre

5

Je ne suis pas sûr de ce que vous demandez - essayez-vous d'obtenir des éléments individuels de chaque groupe? dans une autre liste? Si oui, SelectMany est probablement ce que vous cherchez.

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(); 

Autre possibilité:

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


Réponse à éditer

Il y a une surcharge de Sélectionnez qui comprend également un index entier - vous pouvez l'utiliser pour filtrer tous les impairs ou même des objets pour obtenir la moitié de l'ensemble.

Vous pouvez changer à quelque chose comme

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() 


Je commence à penser que je ne comprends pas la question. Si le problème est que vous avez des données comme

condition1: objectiveID = 2 problemID = 100 
condition2: objectiveID = 2 problemID = 101 

et vous ne voulez pas deux problemIDs différents pour le même objectiveID, vous pouvez utiliser GroupBy/SelectMany/TAKE pour réduire à un seul problème par objectiveID

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

Eh bien, je suppose que ce groupe d'utilisation serait une bonne idée .. s'il vous plaît, vérifiez la mise à jour .. parce que le problème est, plus tard .. Je dois annuler ce groupe par – Darf

+0

t voir tous les bys de groupe dans votre code mis à jour, que fait "la moitié des éléments de chaque groupe par." signifier? – Jimmy

+0

Eh bien, le code ci-dessous que j'ai posté, je suppose que plus tard, je dois utiliser un groupe pour le faire .. Je veux vraiment obtenir la moitié des problèmes de chaque OBJECTIVEID – Darf

0

Pour un IEnumerable arbitraire, vous pouvez obtenir une répartition alternée en deux listes en utilisant: -

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); 
Questions connexes