Comment concaténer deux tableaux en C #?

267
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?

hwiechers
la source
8
Qu'entendez-vous par «efficace»? Le code est assez court car il est donc je suppose que vous voulez dire efficace en termes de CPU / RAM?
TToni
4
Non, un coup d'œil rapide avec Reflector montre qu'il utilise un tampon double lorsque plein
erikkallen
Soyons clairs, j'ai besoin que z soit de type int [].
hwiechers
4
Je ne suis pas vraiment préoccupé par l'efficacité. (J'ai dit plus facile ou plus efficace.) J'ai posé la question pour vérifier comment d'autres personnes géraient cette tâche courante.
hwiechers

Réponses:

331
var z = new int[x.Length + y.Length];
x.CopyTo(z, 0);
y.CopyTo(z, x.Length);
Zed
la source
8
@manthrax -> Pour sa défense, C # a tendance à favoriser les listes qui sont beaucoup plus puissantes que les tableaux. Il semble que le seul objectif fonctionnel de l'utilisation des tableaux soit pour les appels Interop (Unmanaged C ++).
Levi Fuller du
@LeviFuller Un autre endroit où C # utilise un tableau est avec des paramsparamètres à nombre variable .
ChrisW
1
@LeviFuller - il est étrange que de nombreuses routines système retournent des tableaux au lieu de listes. par exemple, System.IO.Directory.GetFiles()renvoie un tableau de chaînes.
orion elenzil
4
Ce n'est pas étrange. Un tableau est immuable, une liste ne l'est pas. Une liste utilise également plus de mémoire qu'un tableau, sauf si TrimExcess est appelé (ce qui ne se produit pas dans ToList)
CSharpie
1
Le tableau est également plus rapide que la liste lors de l'accès aux données, car la liste enveloppe simplement le tableau à l'intérieur et a une surcharge pour appeler l'indexeur.
C0DEF52
84

Essaye ça:

List<int> list = new List<int>();
list.AddRange(x);
list.AddRange(y);
int[] z = list.ToArray();
Adriaan Stander
la source
5
Ou mêmeList<int> list = new List<int>(x);
Matthew Scharley
7
Comment est-ce plus efficace que x.Concat (y)? Cela fonctionne et tout, je me demande simplement s'il y a quelque chose qui le rend meilleur?
Mike Two
7
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
Mike Two
5
@Mathew Scharley. La question demande une solution plus efficace. Je sais que le titre sonne comme n'importe quelle ancienne combinaison, mais la question complète va au-delà. En lisant certaines des réponses, j'ai l'impression que certaines personnes répondent au titre. J'ai donc pensé que cette réponse devrait probablement mentionner l'efficacité si elle mérite les votes positifs puisque cela semblait être le point de la question.
Mike Two
2
s'avère que l'AddRange est en fait un processus assez coûteux, donc la première réponse sur ce forum devrait être l'approche préférée: dotnetperls.com/insertrange
Liam
49

Vous pouvez é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}
Marc Gravell
la source
1
N'y a-t-il pas déjà une méthode d'extension qui fonctionne sur n'importe quel IEnumerable?
Mike Two
2
Oui, et je l'utiliserais volontiers pour la plupart des cas. Mais ils ont beaucoup de frais généraux. Ça dépend; 98% du temps, les frais généraux sont très bien. Si vous êtes dans le 2%, cependant, un travail direct de memcopy / array est pratique.
Marc Gravell
1
@nawfal, comment est Copyplus rapide que CopyTo? Envie d'élaborer?
skrebbel
1
La mine @skrebbel était un commentaire inexact. J'ai fait quelques tests à l'époque et j'ai trouvé Copier plus rapidement. Mais maintenant, il semble qu'ils soient juste égaux. Ce que j'aurais pu trouver à l'époque pourrait être que l'approche globale de Marc est plus efficace car il repasse la même instance alors que dans l'approche de Zed, il crée un nouveau tableau. Excuses :)
nawfal
1
@Shimmy Ce ne serait pas le cas. À l'intérieur de cette méthode, x n'est qu'une variable locale, le passage de x comme référence à la méthode de redimensionnement créerait un nouveau tableau et modifierait (la variable locale) x pour pointer vers lui. Ou pour reformuler: x passé dans le redimensionnement et x à l'intérieur de la méthode d'extension est la même variable, mais x n'est pas passé dans la méthode d'extension comme une référence, donc x est une variable différente de la variable dans la portée à partir de laquelle cette extension a été appelée .
AnorZaken
40

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ène 3+ à 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'utilisation:

        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}
deepee1
la source
Belle fonction, merci! Changé params T[][]pour this T[][]en faire une extension.
Mark
Salut les gars, cette fonction ressemble à ce que je cherchais mais une idée de comment y parvenir? lien @Mark
George B
31

Ça y est:

using System.Linq;

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

// Concatenate array1 and array2.
var result1 = array1.Concat(array2);
Roland
la source
4
Vous voulez dire que int[] result = array1.ToList().Concat(array2.ToList()).toArray();vous ne pouvez pas appliquer Concat sur des tableaux directement, je crois
Michail Michailidis
4
Cette solution - z = x.Concat (y) - est mentionnée dans la question d'origine ci-dessus.
Jon Schneider
1
C'est ce qui se passe sanstoArray() Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
Tibor Udvari
2
Ce n'est pas une réponse directe. OP a demandé int[] result = ?, vous cachez le problème de votre réponse derrière vous varen ce que votre résultat sera IEnumerable<int>non int[]. (l'une des raisons pour lesquelles je n'aime pas varles retours de méthode)
David S.
2
Cette méthode est celle qui est utilisée dans la question, donc cette réponse ne fournit aucune nouvelle information, et sans l' .ToArray()appel, ce code ne retournera pas un tableau réel, donc c'est aussi une réponse incorrecte.
Mani Gandham
10

Vous pouvez retirer l'appel ToArray () de la fin. Y a-t-il une raison pour laquelle vous avez besoin que ce soit un tableau après l'appel à Concat?

L'appel de Concat crée un itérateur sur les deux tableaux. Il ne crée pas de nouveau tableau, vous n'avez donc pas utilisé plus de mémoire pour un nouveau tableau. Lorsque vous appelez ToArray, vous créez en fait un nouveau tableau et utilisez la mémoire du nouveau tableau.

Donc, si vous avez juste besoin d'itérer facilement les deux, appelez simplement Concat.

Mike Two
la source
8

Je sais que l'OP n'était que légèrement curieux de performances. Ces tableaux plus grands peuvent obtenir un résultat différent (voir @kurdishTree). Et que cela n'a généralement pas d'importance (@ jordan.peoples). Néanmoins, j'étais curieux et j'ai donc perdu la tête (comme l'expliquait @TigerShark) .... Je veux dire que j'ai écrit un test simple basé sur la question d'origine .... et toutes les réponses ....

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace concat
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] x = new int [] { 1, 2, 3};
            int[] y = new int [] { 4, 5 };


            int itter = 50000;
            Console.WriteLine("test iterations: {0}", itter);

            DateTime startTest = DateTime.Now;
            for(int  i = 0; i < itter; i++)
            {
                int[] z;
                z = x.Concat(y).ToArray();
            }
            Console.WriteLine ("Concat Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks );

            startTest = DateTime.Now;
            for(int  i = 0; i < itter; i++)
            {
                var vz = new int[x.Length + y.Length];
                x.CopyTo(vz, 0);
                y.CopyTo(vz, x.Length);
            }
            Console.WriteLine ("CopyTo Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks );

            startTest = DateTime.Now;
            for(int  i = 0; i < itter; i++)
            {
                List<int> list = new List<int>();
                list.AddRange(x);
                list.AddRange(y);
                int[] z = list.ToArray();
            }
            Console.WriteLine("list.AddRange Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.Concat(x, y);
            }
            Console.WriteLine("Concat(x, y) Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.ConcatArrays(x, y);
            }
            Console.WriteLine("ConcatArrays Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.SSConcat(x, y);
            }
            Console.WriteLine("SSConcat Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int k = 0; k < itter; k++)
            {
                int[] three = new int[x.Length + y.Length];

                int idx = 0;

                for (int i = 0; i < x.Length; i++)
                    three[idx++] = x[i];
                for (int j = 0; j < y.Length; j++)
                    three[idx++] = y[j];
            }
            Console.WriteLine("Roll your own Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);


            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.ConcatArraysLinq(x, y);
            }
            Console.WriteLine("ConcatArraysLinq Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] z = Methods.ConcatArraysLambda(x, y);
            }
            Console.WriteLine("ConcatArraysLambda Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                List<int> targetList = new List<int>(x);
                targetList.Concat(y);
            }
            Console.WriteLine("targetList.Concat(y) Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);

            startTest = DateTime.Now;
            for (int i = 0; i < itter; i++)
            {
                int[] result = x.ToList().Concat(y.ToList()).ToArray();
            }
            Console.WriteLine("x.ToList().Concat(y.ToList()).ToArray() Test Time in ticks: {0}", (DateTime.Now - startTest).Ticks);
        }
    }
    static class Methods
    {
        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;
        }

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


        public static T[] SSConcat<T>(this T[] first, params T[][] arrays)
        {
            int length = first.Length;
            foreach (T[] array in arrays)
            {
                length += array.Length;
            }
            T[] result = new T[length];
            length = first.Length;
            Array.Copy(first, 0, result, 0, first.Length);
            foreach (T[] array in arrays)
            {
                Array.Copy(array, 0, result, length, array.Length);
                length += array.Length;
            }
            return result;
        }

        public static T[] ConcatArraysLinq<T>(params T[][] arrays)
        {
            return (from array in arrays
                    from arr in array
                    select arr).ToArray();
        }

        public static T[] ConcatArraysLambda<T>(params T[][] arrays)
        {
            return arrays.SelectMany(array => array.Select(arr => arr)).ToArray();
        }
    }

}

Le résultat a été:

entrez la description de l'image ici

Lancez vos propres victoires.

fusionner
la source
En toute justice pour les méthodes qui utilisaient les méthodes, les méthodes ont probablement ajouté environ 10 000 ticks sur mon système.
fusionner
1
J'ai exécuté votre code dans Visual Studio 2013 en mode de publication et j'ai constaté que, si le tableau testé n'est pas aussi petit que le vôtre (comme 1000 éléments), CopyToil sera le plus rapide et ~ 3 fois plus rapide que Roll your own.
M. Ree
@ Mr.Ree Oui, mon tableau était vraiment minuscule n'est-ce pas. Merci. Serait intéressé de voir si la copie de bloc fait encore mieux ...
fusionner le
7

Soyez prudent avec la Concatméthode. La post concaténation de tableau en C # explique que:

var z = x.Concat(y).ToArray();

Sera inefficace pour les grands tableaux. Cela signifie que la Concatméthode est uniquement pour les tableaux de taille moyenne (jusqu'à 10000 éléments).

kurdishTree
la source
2
Que faire avec des tableaux contenant plus de 10 000 éléments?
alex
6
public static T[] Concat<T>(this T[] first, params T[][] arrays)
{
    int length = first.Length;
    foreach (T[] array in arrays)
    {
        length += array.Length;
    }
    T[] result = new T[length];
    length = first.Length;
    Array.Copy(first, 0, result, 0, first.Length);
    foreach (T[] array in arrays)
    {
        Array.Copy(array, 0, result, length, array.Length);
        length += array.Length;
    }
    return result;
}
Sergey Shteyn
la source
2
Chez StackOverflow, veuillez ne pas simplement coller du code, mais aussi expliquer votre approche. Dans ce cas spécifique, vous devrez peut-être également expliquer ce que votre réponse tardive ajoute aux réponses déjà données (et acceptées)
Gert Arnold
1
Je ne sais pas ce que "cela" fait avant le premier paramètre, mais pour le reste, c'est une excellente fonction. Générique et avec une quantité infinie de paramètres.
Nyerguds
2
Salut Nyerguds. Pour répondre à votre question, le mot clé "this" est utilisé pour faire de la fonction une méthode d'extension. Pour plus d'informations sur les méthodes d'extension, consultez cet article MSDN
JFish222
6

Plus efficace (plus rapide) à utiliser Buffer.BlockCopyplus Array.CopyTo,

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

int[] z = new int[x.Length + y.Length];
var byteIndex = x.Length * sizeof(int);
Buffer.BlockCopy(x, 0, z, 0, byteIndex);
Buffer.BlockCopy(y, 0, z, byteIndex, y.Length * sizeof(int));

J'ai écrit un programme de test simple qui «réchauffe la gigue», compilé en mode de publication et l'ai exécuté sans débogueur attaché, sur ma machine.

Pour 10 000 000 d'itérations de l'exemple de la question

Concat a pris 3088ms

CopyTo a pris 1079ms

BlockCopy a pris 603ms

Si je modifie les tableaux de test en deux séquences de 0 à 99, j'obtiens des résultats similaires à cela,

Concat a pris 45945ms

CopyTo a pris 2230ms

BlockCopy a pris 1689ms

À partir de ces résultats, je peux affirmer que les méthodes CopyToet BlockCopysont beaucoup plus efficaces que Concatet, en outre, si la performance est un objectif, BlockCopya une valeur supérieure àCopyTo .

Pour mettre en garde contre cette réponse, si les performances n'ont pas d'importance, ou s'il y aura peu d'itérations, choisissez la méthode que vous trouvez la plus simple. Buffer.BlockCopyoffre une certaine utilité pour la conversion de type au-delà de la portée de cette question.

Jodrell
la source
6

Réponse tardive :-).

public static class ArrayExtention
    {

        public static T[] Concatenate<T>(this T[] array1, T[] array2)
        {
            T[] result = new T[array1.Length + array2.Length];
            array1.CopyTo(result, 0);
            array2.CopyTo(result, array1.Length);
            return result;
        }

    }
Saleh Saeednia
la source
3

La structure la plus efficace en termes de RAM (et CPU) pour contenir le tableau combiné serait une classe spéciale qui implémente IEnumerable (ou si vous le souhaitez dérive même de Array) et relie en interne les tableaux d'origine pour lire les valeurs. AFAIK Concat fait exactement cela.

Dans votre exemple de code, vous pouvez cependant omettre le .ToArray (), ce qui le rendrait plus efficace.

TToni
la source
3

Désolé de faire revivre un vieux fil, mais qu'en est-il de ceci:

static IEnumerable<T> Merge<T>(params T[][] arrays)
{
    var merged = arrays.SelectMany(arr => arr);

    foreach (var t in merged)
        yield return t;
}

Puis dans votre code:

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

var z=Merge(x, y);  // 'z' is IEnumerable<T>

var za=z.ToArray(); // 'za' is int[]

Jusqu'à ce que vous appeliez .ToArray(), .ToList()ou .ToDictionary(...), que la mémoire ne soit pas allouée, vous êtes libre de «créer votre requête» et d'appeler l'un de ces trois pour l'exécuter ou simplement de les parcourir tous en utilisant la foreach (var i in z){...}clause qui renvoie un élément à la fois à partir de layield return t; au dessus...

La fonction ci-dessus peut être transformée en extension comme suit:

static IEnumerable<T> Merge<T>(this T[] array1, T[] array2)
{
    var merged = array1.Concat(array2);

    foreach (var t in merged)
        yield return t;
}

Donc, dans le code, vous pouvez faire quelque chose comme:

int[] x1={1, 2, 3};
int[] x2={4, 5, 6};
int[] x3={7, 8};

var z=x1.Merge(x2).Merge(x3);   // 'z' is IEnumerable<T>

var za=z.ToArray(); // 'za' is int[]

Le reste est le même qu'avant.

Une autre amélioration à ce serait en train de changer T[]dans IEnumerable<T>( de sorte que le params T[][]deviendraitparams IEnumerable<T>[] ) pour rendre ces fonctions acceptent plus que des tableaux.

J'espère que cela t'aides.

nurchi
la source
2

Vous pouvez le faire comme vous l'avez mentionné, ou si vous voulez être vraiment manuel à ce sujet, vous pouvez rouler votre propre boucle:

        string[] one = new string[] { "a", "b" };
        string[] two = new string[] { "c", "d" };
        string[] three;

        three = new string[one.Length + two.Length];

        int idx = 0;

        for (int i = 0; i < one.Length; i++)
            three[idx++] = one[i];
        for (int j = 0; j < two.Length; j++)
            three[idx++] = two[j];
dreadwail
la source
@nawfal Je pense que cela dépendra de la taille du tableau. Cela a remporté mon test de petite taille.
fusionner
2

J'ai trouvé une solution élégante d'une ligne utilisant l' expression LINQ ou Lambda , les deux fonctionnent de la même manière (LINQ est converti en Lambda lorsque le programme est compilé). La solution fonctionne pour tout type de tableau et pour n'importe quel nombre de tableaux.

Utilisation de LINQ:

public static T[] ConcatArraysLinq<T>(params T[][] arrays)
{
    return (from array in arrays
            from arr in array
            select arr).ToArray();
}

Utilisation de Lambda:

public static T[] ConcatArraysLambda<T>(params T[][] arrays)
{
    return arrays.SelectMany(array => array.Select(arr => arr)).ToArray();
}

J'ai prévu les deux selon ses préférences. Performance sage de @Sergey Shteyn ou de @ deepee1 solutions sont un peu plus rapide, l' expression Lambda étant le plus lent. Le temps nécessaire dépend du ou des types d'éléments de tableau, mais à moins qu'il y ait des millions d'appels, il n'y a pas de différence significative entre les méthodes.

Marko Grešak
la source
1

Ce dont vous devez vous souvenir, c'est que lorsque vous utilisez LINQ, vous utilisez une exécution différée. Les autres méthodes décrites ici fonctionnent toutes parfaitement, mais elles sont exécutées immédiatement. De plus, la fonction Concat () est probablement optimisée de manières que vous ne pouvez pas faire vous-même (appels aux API internes, appels au système d'exploitation, etc.). Quoi qu'il en soit, à moins que vous n'ayez vraiment besoin d'essayer et d'optimiser, vous êtes actuellement sur la voie de "la racine de tous les maux";)

Siewers
la source
1

Essayez ce qui suit:

T[] r1 = new T[size1];
T[] r2 = new T[size2];

List<T> targetList = new List<T>(r1);
targetList.Concat(r2);
T[] targetArray = targetList.ToArray();
کی‌راد عباسی
la source
1

Voici ma réponse:

int[] z = new List<string>()
    .Concat(a)
    .Concat(b)
    .Concat(c)
    .ToArray();

Cette méthode peut être utilisée au niveau de l'initialisation, par exemple pour définir une concaténation statique de tableaux statiques:

public static int[] a = new int [] { 1, 2, 3, 4, 5 };
public static int[] b = new int [] { 6, 7, 8 };
public static int[] c = new int [] { 9, 10 };

public static int[] z = new List<string>()
    .Concat(a)
    .Concat(b)
    .Concat(c)
    .ToArray();

Cependant, il est livré avec deux mises en garde que vous devez considérer:

  • La Concat méthode crée un itérateur sur les deux tableaux: elle ne crée pas de nouveau tableau, ce qui est efficace en termes de mémoire utilisée: cependant, le ToArray  annulera cet avantage, car il créera en fait un nouveau tableau et occupera la mémoire du nouveau tableau.
  • Comme l'a dit @Jodrell, Concatserait plutôt inefficace pour les grands tableaux: il ne devrait être utilisé que pour les tableaux de taille moyenne.

Si viser la performance est un must, la méthode suivante peut être utilisée à la place:

/// <summary>
/// Concatenates two or more arrays into a single one.
/// </summary>
public static T[] Concat<T>(params T[][] arrays)
{
    // return (from array in arrays from arr in array select arr).ToArray();

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

Ou (pour les fans de one-liners):

int[] z = (from arrays in new[] { a, b, c } from arr in arrays select arr).ToArray();

Bien que cette dernière méthode soit beaucoup plus élégante, la première est nettement meilleure pour les performances.

Pour plus d'informations, veuillez vous référer à cet article sur mon blog.

Darkseal
la source
0

Pour int [] ce que vous avez fait me semble bien. la réponse d'astander fonctionnerait également bien List<int>.

mezoid
la source
2
Concat fonctionnerait également pour List <int>. C'est ce qui est génial avec Concat, il fonctionne sur n'importe quel IEnumerable <>
Mike Two
0

Pour les tableaux plus petits <10000 éléments:

using System.Linq;

int firstArray = {5,4,2};
int secondArray = {3,2,1};

int[] result = firstArray.ToList().Concat(secondArray.ToList()).toArray();
Michail Michailidis
la source
pourquoi utiliser Linq quand vous n'êtes pas obligé?!
ina
0
static class Extensions
{
    public static T[] Concat<T>(this T[] array1, params T[] array2) => ConcatArray(array1, array2);

    public static T[] ConcatArray<T>(params T[][] arrays)
    {
        int l, i;

        for (l = i = 0; i < arrays.Length; l += arrays[i].Length, i++);

        var a = new T[l];

        for (l = i = 0; i < arrays.Length; l += arrays[i].Length, i++)
            arrays[i].CopyTo(a, l);

        return a;
    }
}

Je pense que la solution ci-dessus est plus générale et plus légère que les autres que j'ai vues ici. Il est plus général car il ne limite pas la concaténation pour seulement deux tableaux et est plus léger car il n'utilise ni LINQ ni List.

Notez que la solution est concise et que la généralité ajoutée n'ajoute pas de surcharge d'exécution importante.

drowa
la source
Je recommanderais d'essayer de trouver de nouvelles questions ou celles qui n'ont pas déjà de nombreuses réponses - dont une à peu près comme la vôtre.
Andrew Barber
J'ai proposé cette solution car je pense qu'elle résume ce qui est bon des autres. Il a été conçu.
drowa
-2

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

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

Milad Doraki
la source
2
Unionn'est pas un très bon moyen de le faire car il appelle Distinctet supprime implicitement tous les doublons de la collection jointe. Concatc'est beaucoup mieux, mais c'est déjà dans la question d'origine.
nurchi
-3
int[] scores = { 100, 90, 90, 80, 75, 60 };
int[] alice = { 50, 65, 77, 90, 102 };
int[] scoreBoard = new int[scores.Length + alice.Length];

int j = 0;
for (int i=0;i<(scores.Length+alice.Length);i++)  // to combine two arrays
{
    if(i<scores.Length)
    {
        scoreBoard[i] = scores[i];
    }
    else
    {
        scoreBoard[i] = alice[j];
        j = j + 1;

    }
}


for (int l = 0; l < (scores.Length + alice.Length); l++)
{
    Console.WriteLine(scoreBoard[l]);
}
presty prajna
la source