¿Cómo puedo obtener la mitad de los elementos de una lista?

El problema es: obtuve una lista de elementos y luego uso agrupar por. Necesito obtener otra lista donde contiene la mitad de los elementos de cada grupo.

¿Cómo puedo hacer eso? Estoy usando LINQ.

ACTUALIZACIÓN:

Esta es la primera lista que recibo.

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

Ese es el original que estoy usando. A partir de ese, solo quiero obtener la mitad de los problemas de cada OBJECTIVEID.

Si en el enummerable tengo 2 elementos del mismo ID de objetivo, debo obtener solo uno. Si tengo un problema, debo obtener solo uno, si tengo 5, tendré 2 o 3.

preguntado el 30 de agosto de 11 a las 22:08

por favor muestre algún código fuente ... -

¿Cómo defines la mitad? ¿Primera mitad / última mitad? o elementos alternativos? -

Como más te guste ... para mí, será bueno primero o alternativo. Creo que eso no sería un problema.

2 Respuestas

No estoy seguro de lo que está preguntando: ¿está tratando de incluir elementos individuales de cada grupo en otra lista? Si es así, SelectMany es probablemente lo que está buscando.

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

Alternativamente:

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


Respuesta a editar

Hay una sobrecarga de Seleccionar que también incluye un índice entero; puede usarlo para filtrar todos los elementos pares o impares para obtener la mitad del conjunto.

Podrías cambiarlo a algo como

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


Empiezo a pensar que no entiendo la pregunta. Si el problema es que tienes datos como

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

y no desea dos ID de problema diferentes para el mismo ID de objetivo, puede usar GroupBy / SelectMany / Take para reducir a solo un problema por ID de objetivo

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

Respondido 31 ago 11, 03:08

Bueno, supongo que usar grupo sería una buena idea ... por favor, revisa la actualización ... porque el problema es que, más tarde ... necesito deshacer ese grupo por - Darf

No veo ningún bys de grupo en su código actualizado, ¿qué significa "la mitad de los elementos de cada grupo"? ¿significar? - palanqueta

Bueno, el siguiente código que publiqué supuse más tarde que necesito usar un grupo para hacer eso ... Realmente quiero obtener la mitad de los problemas de cada OBJECTIVEID - Darf

Entiendo tu idea. No estoy seguro de cómo puedo agregar este código ... entonces, ¿no tengo la necesidad de usar un grupo? - Darf

Necesita usar el groupby, solo necesita usar un selectmany(group => group.Take(1)) para lograr su objetivo de "solo tomar un problema para cada ID de objetivo" - palanqueta

Por un arbitrario IEnumerable puede obtener una división alterna en dos listas usando: -

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

Respondido 31 ago 11, 03:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.