Moyen le plus efficace pour append des tableaux en C #?

Je tire des données d’un ActiveX de la vieille école sous la forme de tableaux de doubles. Je ne connais pas initialement le nombre final d’échantillons que je vais effectivement récupérer.

Quel est le moyen le plus efficace de concaténer ces tableaux en C # lorsque je les retire du système?

Vous ne pouvez pas append à un tableau réel – la taille d’un tableau est fixée au moment de la création. Au lieu de cela, utilisez une List qui peut évoluer à sa guise.

Vous pouvez également conserver une liste de tableaux et les concaténer tous lorsque vous avez tout saisi.

Voir l’article de Eric Lippert sur les tableaux pour plus de détails et de perspicacité que ce que je pourrais fournir de manière réaliste 🙂

Je pense que si vous avez deux tableaux du même type que vous souhaitez combiner dans une troisième baie, il existe un moyen très simple de le faire.

voici le code:

 Ssortingng[] theHTMLFiles = Directory.GetFiles(basePath, "*.html"); Ssortingng[] thexmlFiles = Directory.GetFiles(basePath, "*.xml"); List finalList = new List(theHTMLFiles.Concat(thexmlFiles)); Ssortingng[] finalArray = finalList.ToArray(); 

Je recommande la réponse trouvée ici: Comment concaténer deux tableaux en C #?

par exemple

 var z = new int[x.Length + y.Length]; x.CopyTo(z, 0); y.CopyTo(z, x.Length); 

La concaténation de tableaux est simple avec les extensions linq standard avec .Net 4

La plus grande chose à retenir est que linq fonctionne avec les objects IEnumerable , donc pour obtenir un tableau comme résultat, vous devez utiliser la méthode .ToArray() à la fin

Exemple de concaténation de tableaux de deux octets:

 byte[] firstArray = {2,45,79,33}; byte[] secondArray = {55,4,7,81}; byte[] result = firstArray.Concat(secondArray).ToArray(); 

La solution semble très amusante, mais il est possible de concaténer des tableaux en deux instructions seulement. Lorsque vous manipulez des tableaux à grands octets, je suppose qu’il est inefficace d’utiliser une liste liée pour contenir chaque octet.

Voici un exemple de code pour lire les octets d’un stream et étendre un tableau d’octets à la volée:

     octet [] buf = nouvel octet [8192];
     octet [] résultat = nouvel octet [0];
     int count = 0;
     faire
     {
         count = resStream.Read (buf, 0, buf.Length);
         si (compte! = 0)
         {
             Array.Resize (ref result, result.Length + count);
             Array.Copy (buf, 0, result, result.Length - count, count);
         }
     }
     tandis que (compte> 0);  // plus de données à lire?
     resStream.Close ();

en utilisant cela, nous pouvons append deux tableaux sans aucune boucle.

Je pense que si vous avez deux tableaux du même type que vous souhaitez combiner en un seul, il existe un moyen très simple de le faire.

Voici le code:

 Ssortingng[] TextFils = Directory.GetFiles(basePath, "*.txt"); Ssortingng[] ExcelFils = Directory.GetFiles(basePath, "*.xls"); Ssortingng[] finalArray = TextFils.Concat(ExcelFils).ToArray(); 

ou

 Ssortingng[] Fils = Directory.GetFiles(basePath, "*.txt"); Ssortingng[] ExcelFils = Directory.GetFiles(basePath, "*.xls"); Fils = Fils.Concat(ExcelFils).ToArray(); 

Si vous pouvez faire une approximation du nombre d’éléments qui seront présents à la fin, utilisez la surcharge du facteur de liste qui compte comme paramètre. Vous économiserez des duplications de listes coûteuses. Sinon, vous devez payer pour cela.

Vous n’aurez peut-être pas besoin de concaténer le résultat final dans un tableau contigu. Au lieu de cela, continuez à append à la liste comme suggéré par Jon. Au final, vous aurez un tableau déchiqueté (enfin, presque rectangular en fait). Lorsque vous devez accéder à un élément par index, utilisez le schéma d’indexation suivant:

 double x = list[i / sampleSize][i % sampleSize]; 

L’itération sur un tableau dentelé est également simple:

 for (int iRow = 0; iRow < list.Length; ++iRow) { double[] row = list[iRow]; for (int iCol = 0; iCol < row.Length; ++iCol) { double x = row[iCol]; } } 

Cela vous évite d’allouer de la mémoire et de copier à un coût légèrement inférieur. Le gain de performance net dépend de la taille de vos données, de vos modèles d’access aux données et des contraintes de mémoire.

Voici une classe utilisable basée sur ce que Constantin a dit:

 class Program { static void Main(ssortingng[] args) { FastConcat i = new FastConcat(); i.Add(new int[] { 0, 1, 2, 3, 4 }); Console.WriteLine(i[0]); i.Add(new int[] { 5, 6, 7, 8, 9 }); Console.WriteLine(i[4]); Console.WriteLine("Enumerator:"); foreach (int val in i) Console.WriteLine(val); Console.ReadLine(); } } class FastConcat : IEnumerable { LinkedList _items = new LinkedList(); int _count; public int Count { get { return _count; } } public void Add(T[] items) { if (items == null) return; if (items.Length == 0) return; _items.AddLast(items); _count += items.Length; } private T[] GetItemIndex(int realIndex, out int offset) { offset = 0; // Offset that needs to be applied to realIndex. int currentStart = 0; // Current index start. foreach (T[] items in _items) { currentStart += items.Length; if (currentStart > realIndex) return items; offset = currentStart; } return null; } public T this[int index] { get { int offset; T[] i = GetItemIndex(index, out offset); return i[index - offset]; } set { int offset; T[] i = GetItemIndex(index, out offset); i[index - offset] = value; } } #region IEnumerable Members public IEnumerator GetEnumerator() { foreach (T[] items in _items) foreach (T item in items) yield return item; } #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion } 

La suggestion d’Olmo est très bonne, mais j’appendais ceci: si vous n’êtes pas sûr de la taille, il est préférable de la rendre un peu plus grande qu’un peu plus petite. Lorsqu’une liste est pleine, gardez à l’esprit qu’elle doublera sa taille pour append plus d’éléments.

Par exemple, supposons que vous ayez besoin d’environ 50 éléments. Si vous utilisez une taille de 50 éléments et que le nombre final d’éléments est de 51, vous obtiendrez une liste de 100 tailles avec 49 positions perdues.