¿Cómo llenar dos matrices separadas de una lista delimitada por comas?

Tengo un archivo de texto delimitado por comas que contiene 20 dígitos separados por comas. Estos números representan puntos ganados y puntos posibles para diez asignaciones diferentes. Debemos usarlos para calcular el puntaje final del curso.

Normalmente, iteraré a través de los números, crearé dos sumas, dividiré y terminaré con eso. Sin embargo, nuestra asignación exige que carguemos la lista de números en dos matrices.

así que esto:

10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85

se convierte en esto:

int[10] earned   = {10,20,30,40,45,50,20,45,85};
int[10] possible = {10,20,35,50,50,50,20,90,85};

En este momento, estoy usando

for (x=0;x<10;x++)
{
     earned[x] = scores[x*2]
     poss  [x] = scores[(x*2)+1]
}

que me da los resultados que quiero, pero parece excesivamente torpe.

¿Hay una mejor manera?

0
Puede ejecutar x hasta 20 en pasos de dos. Eso elimina la oscurecida multiplicación.
agregado el autor usr, fuente
@Guvante cierto. No fue una buena idea
agregado el autor usr, fuente
Podrías hacer earned [x/2] , si quisieras aumentar en dos.
agregado el autor Tim S., fuente
@usr: Entonces no podrías hacer earned [x] .
agregado el autor Guvante, fuente
Lo que podrías hacer para que el código sea un poco más robusto es cargar toda la lista en una matriz y luego utilizar un foreach para recorrer cada sección de esta matriz completa y luego usar un contador para determinar cuántas veces has pasado por el ciclo. si el contador es impar, entra en la matriz obtenida o, si es par, entra en la matriz de puntajes, eliminando así la multiplicación y si el tamaño de la lista cambia no hay necesidad de modificar el código.
agregado el autor jgok222, fuente

7 Respuestas

Deshágase de las multiplicaciones "mágicas" y los cálculos del índice de matriz ilegible.

var earned = new List();
var possible = new List();
for (x=0; x

Esto tiene muy poco que necesitaría un comentario de texto. Este es el estándar de oro para el código de auto-documentación.

Inicialmente pensé que la pregunta era una pregunta en C debido a toda la indexación incomprensible. Parecía magia de puntero. Fue muy inteligente.

En mis bases de código generalmente tengo una extensión AsChunked disponible que divide una lista en fragmentos del tamaño dado.

var earned = new List();
var possible = new List();
foreach (var pair in scores.AsChunked(2)) {
     earned.Add(pair[0]);
     possible.Add(pair[1]);
}

Ahora el significado del código es evidente. La magia se ha ido.

Incluso más corto:

var pairs = scores.AsChunked(2);
var earned = pairs.Select(x => x[0]).ToArray();
var possible = pairs.Select(x => x[1]).ToArray();
0
agregado
@MAV luego llame a ToArray al final.
agregado el autor usr, fuente
@MAV No asumiría ese derecho del bate. Además, eso lo convierte en una tarea loca.
agregado el autor usr, fuente
Como esta es una tarea, las matrices pueden ser un requisito.
agregado el autor MAV, fuente
" nuestra tarea exige que carguemos la lista de números en dos matrices ". Interpreto que esto significa que las listas están prohibidas desde el principio. Pero si esta es una solución válida para la asignación de OP, digo "adelante".
agregado el autor MAV, fuente

I would leave your code as is. You are technically expressing very directly what your intent is, every 2nd element goes into each array.

La única forma de mejorar esa solución es comentar por qué se está multiplicando. Pero esperaría que alguien reconozca rápidamente el truco, o reproduzca fácilmente lo que está haciendo. Aquí hay un excesivo ejemplo de cómo comentarlo. No recomendaría usar esto directamente.

for (x=0;x<10;x++)
{
     //scores contains the elements inline one after the other
     earned[x] = scores[x*2]     //Get the even elements into earned
     poss  [x] = scores[(x*2)+1] //And the odd into poss
}

Sin embargo, si realmente no te gusta la multiplicación, puedes seguir el índice de puntajes por separado.

int i = 0;
for (int x = 0; x < 10; x++)
{
    earned[x] = scores[i++];
    poss  [x] = scores[i++];
}

Pero probablemente preferiría su versión ya que no depende del orden de las operaciones.

0
agregado
Creo que el doble incremento de i es difícil de entender. La mutación del estado es más difícil de seguir que las expresiones funcionales.
agregado el autor usr, fuente
@usr: Estoy de acuerdo, no hay realmente una manera "limpia" de hacer esto, que es lo que estaba tratando de expresar.
agregado el autor Guvante, fuente

Lo siguiente debe dividir cada elemento alterno de la lista en las otras dos listas.

int[20] scores = {10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85};

int[10] earned;
int[10] possible;

int a = 0;
for(int x=0; x<10; x++)
{
    earned[x] = scores[a++];
    possible[x] = scores[a++];
}
0
agregado
Tienes dos problemas. x/y se usa a menudo para manejar la matriz matemática, que no está haciendo aquí. También ahora si voltea las líneas internas obtendrá resultados completamente diferentes.
agregado el autor Guvante, fuente
@Guvante He modificado mi respuesta para evitar confusiones con mathmatics de la matriz
agregado el autor AeroX, fuente

Supongo que podrías hacerlo así:

int[] earned = new int[10];
int[] possible = new int[10];
int resultIndex = 0;

for (int i = 0; i < scores.Count; i = i + 2)
{
    earned[resultIndex] = scores[i];
    possible[resultIndex] = scores[i + 1];
    resultIndex++;
}

Debería estar seguro de que se almacena un número igual de valores en los puntajes .

0
agregado

Puedes usar LINQ aquí:

var arrays = csv.Split(',')
                .Select((v, index) => new {Value = int.Parse(v), Index = index})
                .GroupBy(g => g.Index % 2, 
                         g => g.Value, 
                         (key, values) => values.ToArray())
                .ToList();

y entonces

var earned = arrays[0];
var possible  = arrays[1];
0
agregado
var res = grades.Select((x, i) => new {x,i}).ToLookup(y=>y.i%2, y=>y.x)
int[] earned = res[0].ToArray();
int[] possible = res[1].ToArray();

Esto agrupará todas las calificaciones en dos categorías según el índice, luego puede hacer ToArray si necesita el resultado en forma de matriz.

0
agregado

Aquí hay un ejemplo de mi comentario, por lo que no es necesario cambiar el código, independientemente del tamaño de la lista:

ArrayList Test = new ArrayList { "10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85" };

        int[] earned = new int[Test.Count/2];
        int[] Score = new int[Test.Count/2];

    int Counter = 1;//start at one so earned is the first array entered in to
    foreach (string TestRow in Test)
    {
        if (Counter % 2 != 0)//is the counter even
        {
            int nextNumber = 0;
            for (int i = 0; i < Score.Length; i++)//this gets the posistion for the next array entry
            {
                if (String.IsNullOrEmpty(Convert.ToString(Score[i])))
                {
                    nextNumber = i;
                    break;
                }
            }
            Score[nextNumber] = Convert.ToInt32(TestRow);
        }
        else
        {
            int nextNumber = 0;
            for (int i = 0; i < earned.Length; i++)//this gets the posistion for the next array entry
            {
                if (String.IsNullOrEmpty(Convert.ToString(earned[i])))
                {
                    nextNumber = i;
                    break;
                }
            }
            earned[nextNumber] = Convert.ToInt32(TestRow);
        }
        Counter++

    }
0
agregado
Probablemente ha sido votado negativamente porque hay una serie de errores en su respuesta. He intentado ejecutar tu código y no funciona. También convertir un int a una cadena para probar si es NullOrEmpty ineficiente, especialmente para hacerlo en un for loop con el propósito de contando cuántos elementos ya ha insertado en una matriz int . Sería mucho más eficiente hacer un seguimiento de la posición de la matriz en una variable. Creé un .NET Fiddle example bas
agregado el autor AeroX, fuente
¿Puedo preguntar, por qué el voto hacia abajo? Esta es una solución alternativa al problema que es exactamente lo que la pregunta estaba pidiendo
agregado el autor jgok222, fuente