332 votes

Comment concaténer deux tableaux en C# ?

int[] x = new int [] { 1, 2, 3};
int[] y = new int [] { 4, 5 };

int[] z = // your answer here...

Debug.Assert(z.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));

En ce moment, j'utilise

int[] z = x.Concat(y).ToArray();

Existe-t-il une méthode plus simple ou plus efficace ?

8 votes

Que voulez-vous dire par "efficace" ? Le code est assez court comme ça, donc je suppose que vous voulez dire efficace en termes de CPU/RAM ?

4 votes

Non, un rapide coup d'œil à Reflector montre qu'il utilise un double tampon quand il est plein.

0 votes

Pour être clair, j'ai besoin que z soit de type int[].

396voto

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

11 votes

@manthrax -> Pour sa défense, C# a tendance à favoriser les listes qui sont beaucoup plus puissantes que les tableaux. Il semble que le seul but fonctionnel de l'utilisation des tableaux soit les appels Interop (Unmanaged C++).

1 votes

@LeviFuller Un autre endroit où C# utilise les tableaux est avec les nombres variables. params paramètres.

0 votes

@ChrisW Je considérerais le tableau params plus comme une limitation syntaxique. Si vous devez le concaténer avec un autre tableau, j'opterais toujours pour <array>.ToList()

104voto

astander Points 83138

Essayez ça :

List<int> list = new List<int>();
list.AddRange(x);
list.AddRange(y);
int[] z = list.ToArray();

6 votes

Ou même List<int> list = new List<int>(x);

8 votes

En quoi est-ce plus efficace que x.Concat(y) ? Cela fonctionne et tout, mais je me demande juste s'il n'y a pas quelque chose qui le rende meilleur ?

13 votes

Vous pourriez vouloir faire la première ligne List<int> list = new List<int>(x.Length + y.Length) ; Pour éviter le redimensionnement qui pourrait se produire lorsque vous appelez AddRange

58voto

Marc Gravell Points 482669

Vous pourriez écrire une méthode d'extension :

public static T[] Concat<T>(this T[] x, T[] y)
{
    if (x == null) throw new ArgumentNullException("x");
    if (y == null) throw new ArgumentNullException("y");
    int oldLen = x.Length;
    Array.Resize<T>(ref x, x.Length + y.Length);
    Array.Copy(y, 0, x, oldLen, y.Length);
    return x;
}

Ensuite :

int[] x = {1,2,3}, y = {4,5};
int[] z = x.Concat(y); // {1,2,3,4,5}

1 votes

N'existe-t-il pas déjà une méthode d'extension qui fonctionne sur tout IEnumerable ?

2 votes

Oui, et je l'utiliserais volontiers dans la plupart des cas. Mais ils ont beaucoup de frais généraux. Cela dépend ; dans 98% des cas, les frais généraux ne posent pas de problème. Si vous êtes dans les 2%, cependant, alors un travail direct de memcopy/array est pratique.

1 votes

@nawfal, comment est Copy plus vite que CopyTo ? Pouvez-vous nous en dire plus ?

43voto

Roland Points 61

C'est ici :

using System.Linq;

int[] array1 = { 1, 3, 5 };
int[] array2 = { 0, 2, 4 };

// Concatenate array1 and array2.
var result1 = array1.Concat(array2);

11 votes

Vous voulez dire int[] result = array1.ToList().Concat(array2.ToList()).toArray(); Vous ne pouvez pas appliquer Concat sur des tableaux directement, je crois.

1 votes

Le code est correct, car les tableaux en C# implémentent l'interface IEnumerable. (Voir le 6ème paragraphe de la section Remarques dans la documentation suivante : msdn.microsoft.com/fr/us/library/system.array.aspx )

5 votes

Cette solution -- z = x.Concat(y) -- est mentionnée dans la question originale ci-dessus.

42voto

deepee1 Points 4449

J'ai opté pour une solution plus générale qui permet de concaténer un ensemble arbitraire de tableaux unidimensionnels du même type. (Je concaténais 3+ tableaux à la fois).

Ma fonction :

    public static T[] ConcatArrays<T>(params T[][] list)
    {
        var result = new T[list.Sum(a => a.Length)];
        int offset = 0;
        for (int x = 0; x < list.Length; x++)
        {
            list[x].CopyTo(result, offset);
            offset += list[x].Length;
        }
        return result;
    }

Et l'usage :

        int[] a = new int[] { 1, 2, 3 };
        int[] b = new int[] { 4, 5, 6 };
        int[] c = new int[] { 7, 8 };
        var y = ConcatArrays(a, b, c); //Results in int[] {1,2,3,4,5,6,7,8}

0 votes

Belle fonction, merci ! Modifié params T[][] à this T[][] pour en faire une extension.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X