2012-07-24 4 views
3

J'utilise un moteur de jeu qui ne peut pas sérialiser les listes imbriquées telles que List<List<int>>. Ce dont j'ai besoin, c'est d'une solution rapide qui stockera plusieurs listes dans une seule liste. Je suis sur le point d'écrire cela par moi-même, mais je me demande si des solutions existent déjà.Combiner les listes imbriquées avec la logique

Existe-t-il des wrappers permettant de stocker des listes imbriquées «virtuelles» dans une grande liste tout en offrant les fonctionnalités que vous attendez de listes séparées?

+1

Si elle ne peut pas sérialiser imbriqué listes, ce qui suggère qu'il utilise un sérialiseur non standard ... donc, en supposant que ce soit le cas, que * peut-il sérialiser? –

+0

Il peut sérialiser des listes standard (non imbriquées). – Abdulla

+0

Une raison pour laquelle vous devez utiliser ce sérialiseur, et non standard? –

Répondre

6

Vous pouvez utiliser Enumerable.SelectMany pour aplatir les listes imbriquées:

List<int> flattened = allLists.SelectMany(l => l).ToList(); 

Serait-il possible de Redresser une liste de retour aplatie dans des listes imbriquées ?

Vous pouvez utiliser un Tuple<int, int> pour enregistrer le numéro de la liste d'origine dans Item1 et le nombre lui-même dans Item2.

// create sample data 
var allLists = new List<List<int>>() { 
    new List<int>(){ 1,2,3 }, 
    new List<int>(){ 4,5,6 }, 
    new List<int>(){ 7,8,9 }, 
}; 

List<Tuple<int, int>> flattened = allLists 
    .Select((l, i) => new{ List = l, Position = i + 1 }) 
    .SelectMany(x => x.List.Select(i => Tuple.Create(x.Position, i))) 
    .ToList(); 

// now you have all numbers flattened in one list: 
foreach (var t in flattened) 
{ 
    Console.WriteLine("Number: " + t.Item2); // prints out the number 
} 
// unflatten 
allLists = flattened.GroupBy(t => t.Item1) 
        .Select(g => g.Select(t => t.Item2).ToList()) 
        .ToList(); 
+1

Serait-il possible de dégrader une liste aplatie dans des listes imbriquées? – Abdulla

+0

@Abdulla: J'ai édité ma réponse. –

0

Pouvez-vous préciser si vous êtes après:

  1. Une bibliothèque de sérialisation qui peut représenter des listes imbriquées (par exemple JSON.NET devrait pouvoir).
  2. Une façon d'aplatir les listes
+0

Un moyen d'aplatir et d'aplatir les listes imbriquées. – Abdulla

1

Que diriez-vous quelque chose comme ceci:

Pour aplatir une liste, utilisez quelque chose comme d'autres ont suggéré de faire une liste aplatie Tuples (note, tout le code ci-dessous est non testé):

List<List<int>> myStartingList = new List<List<int>>(); 
List<Tuple<int, int, int>> myFlatList = new List<Tuple<int, int, int>>(); 
for (var iOuter = 0; iOuter < myStartingList.Count; iOuter++) 
    for (var iInner = 0; iInner < myStartingList[iOuter].Count; iInner++) 
     myFlatList.Add(new Tuple<int, int, int>(iOuter, iInner, myStartingList[iOuter][iInner]); 

et Redresser:

List<List<int>> myNestedList = new List<List<int>>(); 
int iOuter=-1; 
foreach (var t in myFlattenedList) 
{ 
    if (iOuter != t.Item1) 
     myNestedList.Add(new List<Int>()); 
    iOuter = t.Item1; 
    myNestedList[t.Item1][t.Item2] = t.Item3; 
}