Как объединить два массива в 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 }));

Щас пользуюсь

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

Есть ли более простой или эффективный метод?


8
Что вы подразумеваете под "эффективными"? Код достаточно короткий, так что я предполагаю, что вы имеете в виду эффективность с точки зрения ЦП / ОЗУ?
TToni

4
Нет, быстрый просмотр Reflector показывает, что он использует двойной буфер при заполнении
erikkallen

Просто будьте ясны, мне нужно, чтобы z было типа int [].
hwiechers

4
Я не особо обеспокоен эффективностью. (Я сказал, проще или эффективнее.) Я задал вопрос, чтобы проверить, как другие люди справляются с этой общей задачей.
hwiechers

Ответы:


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

8
@manthrax -> В свою очередь, C # предпочитает списки, которые намного мощнее массивов. Кажется, единственная функциональная цель использования массивов - для вызовов Interop (Unmanaged C ++).
Леви Фуллер

@LeviFuller Еще одно место, где C # использует массив, это параметры с переменным числом params.
ChrisW

1
@LeviFuller - странно, что многие системные подпрограммы возвращают массивы вместо списков. например, System.IO.Directory.GetFiles()возвращает массив строк.
orion elenzil

4
Это не странно. Массив неизменен, список - нет. Кроме того, List использует больше памяти, чем массив, если не вызывается TrimExcess (чего не происходит в ToList)
CSharpie

1
Кроме того, при обращении к данным массив работает быстрее, чем список, поскольку список просто оборачивает массив и накладывает дополнительные расходы на вызов индексатора.
C0DEF52

84

Попробуй это:

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

5
Или дажеList<int> list = new List<int>(x);
Мэтью Шарли

7
Как это эффективнее, чем x.Concat (y)? Это работает, и все, мне просто интересно, есть ли что-то, что делает это лучше?
Майк Два

7
Вы можете сделать первую строку List <int> list = new List <int> (x.Length + y.Length); Чтобы избежать изменения размера, которое может произойти при вызове AddRange
Mike Two

5
@ Мэтью Шарли. Вопрос требует более эффективного решения. Я знаю, что название делает его звучащим, как любая старая комбинация, но полный вопрос выходит за рамки этого. Читая некоторые ответы, я просто чувствую, что некоторые люди отвечают на заголовок. Поэтому я подумал, что в этом ответе, вероятно, следует упомянуть эффективность, если он заслуживает положительных отзывов, поскольку это, казалось, является вопросом вопроса.
Майк Два

2
Оказывается, что AddRange на самом деле довольно дорогой процесс, поэтому первым ответом на этой доске должен быть предпочтительный подход: dotnetperls.com/insertrange
Liam

49

Вы можете написать метод расширения:

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

Затем:

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

1
Не существует ли уже метод расширения, который работает на любом IEnumerable?
Майк Два

2
Да, и я бы с удовольствием использовал это в большинстве случаев. Но у них много накладных расходов. Это зависит; 98% времени накладные расходы в порядке. Если вы находитесь в 2%, тогда некоторая прямая работа с memcopy / array будет полезна.
Марк Гравелл

1
@nawfal, как Copyбыстрее чем CopyTo? Хотите разработать?
скреббель

1
Мой @skrebbel был неточным комментарием. Тогда я провел некоторое тестирование и нашел Копию быстрее. Но сейчас кажется, что они просто равны. Тогда я мог бы обнаружить, что в целом подход Марка более эффективен, поскольку он передает тот же экземпляр назад, в то время как в подходе Зеда он создает новый массив. Извинения :)
nawfal

1
@ Шимми Это не будет. Внутри этого метода x является лишь локальной переменной, передача x в качестве ссылки методу resize создаст новый массив и изменит (локальную переменную) x, чтобы указать на него. Или перефразируя: x, переданный в resize, и x внутри метода расширения - это та же переменная, но x не передается в метод расширения как ref, поэтому x - это переменная, отличная от переменной в области, из которой это расширение было вызвано ,
AnorZaken

40

Я остановился на более универсальном решении, которое позволяет объединять произвольный набор одномерных массивов одного типа. (Я объединял 3+ за раз.)

Моя функция:

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

И использование:

        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}

Отличная функция, спасибо! Изменено, params T[][]чтобы this T[][]сделать его расширением.
Марк

Привет, ребята, эта функция выглядит как то, что я искал, но есть идеи, как мне этого добиться? ссылка @Mark
Джордж Б

31

Это оно:

using System.Linq;

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

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

4
Я имею в виду, int[] result = array1.ToList().Concat(array2.ToList()).toArray();Вы не можете применять Concat непосредственно к массивам
Михаил Михайлидис,

4
Это решение - z = x.Concat (y) - упомянуто в первоначальном вопросе выше.
Джон Шнайдер

1
Это то, что происходит безtoArray() Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. An explicit conversion exists (are you missing a cast?)
Тибор Удвари

2
Это не прямой ответ. ОП спросил int[] result = ?, вы скрываете проблему своего ответа за varтем, что ваш результат будет IEnumerable<int>, а не int[]. (одна из причин, почему мне не нравятся varвозвраты метода)
Дэвид С.

2
Этот метод используется в вопросе, поэтому в этом ответе нет новой информации, и без .ToArray()вызова этот код не будет возвращать фактический массив, поэтому это также неверный ответ.
Мани Гэндхэм

10

Вы можете снять вызов ToArray () с конца. Есть ли причина, по которой вам нужен массив после вызова Concat?

Вызов Concat создает итератор для обоих массивов. Он не создает новый массив, поэтому вы не использовали больше памяти для нового массива. Когда вы вызываете ToArray, вы фактически создаете новый массив и занимает память для нового массива.

Так что, если вам просто нужно перебрать и то и другое, просто вызовите Concat.


8

Я знаю, что OP был только немного любопытен относительно производительности. Эти большие массивы могут получить другой результат (см. @KurdishTree). И это обычно не имеет значения (@ jordan.peoples). Тем не менее, мне было любопытно, и поэтому я сошел с ума (как объяснял @TigerShark) .... Я имею в виду, что я написал простой тест на основе исходного вопроса .... и всех ответов ....

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

}

Результат был:

введите описание изображения здесь

Ролл свои собственные победы.


Справедливости ради методов, которые использовали методы, методы, вероятно, добавили примерно 10000 тиков в моей системе.
объединение

1
Я запустил ваш код в Visual Studio 2013 в режиме выпуска и обнаружил, что, если тестируемый массив не такой маленький, как ваш (например, 1000 элементов), CopyToон будет самым быстрым и примерно в 3 раза быстрее, чем Roll your own.
Мистер Ри

@ Mr.Ree Да, мой массив был действительно крошечным, не так ли? Спасибо. Было бы интересно посмотреть, будет ли блок-копия еще лучше ...
объединение

7

Будьте осторожны с Concatметодом. Сообщение конкатенации массивов в C # объясняет, что:

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

Будет неэффективно для больших массивов. Это означает, что Concatметод предназначен только для массивов размера meduim (до 10000 элементов).


2
Что делать с массивами, содержащими более 10 000 элементов?
Алекс

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

2
В StackOverflow, пожалуйста, не только вставьте код, но и объясните свой подход. В этом конкретном случае вам также может понадобиться объяснить, что ваш поздний ответ добавляет к уже предоставленным (и принятым) ответам
Герт Арнольд

1
Не уверен, что это «это» делает перед первым параметром, но для остальных это отличная функция. Универсальный и с бесконечным количеством параметров.
Нергудс

2
Привет, Нергудс. Чтобы ответить на ваш вопрос, ключевое слово «this» используется, чтобы сделать функцию методом расширения. Для получения дополнительной информации о методах расширения ознакомьтесь с этой статьей MSDN
JFish222

6

Более эффективный (быстрее) , чтобы использовать Buffer.BlockCopyболее 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));

Я написал простую тестовую программу, которая «подогревает джиттер», скомпилирован в режиме релиза и запускал ее без подключенного отладчика на моей машине.

За 10 000 000 итераций примера в вопросе

Конкат занял 3088мс

Копирование заняло 1079мс

BlockCopy занял 603 мс

Если я изменю тестовые массивы на две последовательности от 0 до 99, то я получу результаты, подобные этим,

Concat занял 45945мс

CopyTo заняло 2230мс

BlockCopy занял 1689мс

Из этих результатов можно утверждать , что CopyToи BlockCopyметоды значительно более эффективны , чем Concatи , кроме того, если производительность является целью, BlockCopyимеет значение , превышающееCopyTo .

Чтобы пояснить этот ответ, если производительность не имеет значения, или будет несколько итераций, выберите метод, который вы находите самым простым. Buffer.BlockCopyдействительно предлагает некоторую полезность для преобразования типов, выходящую за рамки этого вопроса.


6

Поздний ответ :-).

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

    }

3

Наиболее эффективной структурой с точки зрения ОЗУ (и ЦП) для хранения объединенного массива будет специальный класс, который реализует IEnumerable (или, если хотите, даже наследуется от Array) и внутренне связывается с исходными массивами для чтения значений. AFAIK Concat делает именно это.

В вашем примере кода вы можете опустить .ToArray (), что сделает его более эффективным.


3

Извините, что оживил старую ветку, но как насчет этого:

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

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

Тогда в вашем коде:

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[]

До тех пор пока вы не вызовете .ToArray(), .ToList()или .ToDictionary(...), память не выделяется, вы можете «построить свой запрос» и либо вызов одного из этих трех , чтобы выполнить его или просто пройти их все, используя foreach (var i in z){...}положение , которое возвращает элемент , в то время отyield return t; выше...

Вышеупомянутая функция может быть превращена в расширение следующим образом:

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

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

Таким образом, в коде вы можете сделать что-то вроде:

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[]

В остальном то же самое, что и раньше.

Еще одно улучшение к этому будет превращаться T[]в IEnumerable<T>(так params T[][]что станетparams IEnumerable<T>[] ) , чтобы сделать эти функции принимают больше , чем просто массивы.

Надеюсь это поможет.


2

Вы можете сделать это так, как вы упомянули, или, если вы хотите получить действительно руководство по этому поводу, вы можете запустить свой собственный цикл:

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

@nawfal Я думаю, это будет зависеть от размера массива. Это выиграло мой тест размером с небольшой массив.
объединение

2

Я нашел элегантное однострочное решение с использованием выражения LINQ или Lambda , оба работают одинаково (LINQ преобразуется в Lambda при компиляции программы). Решение работает для любого типа массива и для любого количества массивов.

Используя LINQ:

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

Я предоставил оба по своему вкусу. С точки зрения производительности решения @Sergey Shteyn или @ deepee1 немного быстрее, а лямбда-выражение - самое медленное. Требуемое время зависит от типа (ов) элементов массива, но если нет миллионов вызовов, между методами нет существенной разницы.


1

Что вам нужно помнить, так это то, что при использовании LINQ вы используете отложенное выполнение. Все описанные здесь методы работают отлично, но они выполняются немедленно. Кроме того, функция Concat (), вероятно, оптимизирована таким образом, что вы не можете делать это самостоятельно (вызовы внутренних API, вызовы ОС и т. Д.). В любом случае, если вам действительно не нужно пытаться оптимизировать, вы находитесь на пути к «корню всего зла»;)


1

Попробуйте следующее:

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

List<T> targetList = new List<T>(r1);
targetList.Concat(r2);
T[] targetArray = targetList.ToArray();

1

Вот мой ответ:

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

Этот метод может использоваться на уровне инициализации, например, для определения статической конкатенации статических массивов:

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();

Тем не менее, он имеет две оговорки, которые необходимо учитывать:

  • Concat Метод создает итератор обоих массивов: он не создает новый массив, таким образом , является эффективным с точки зрения используемой памяти: однако, последующий ToArray  будет отрицать такое преимущество, так как оно будет на самом деле создать новый массив и занимают память для новый массив.
  • Как сказал @Jodrell, это Concatбыло бы довольно неэффективно для больших массивов: его следует использовать только для массивов среднего размера.

Если стремление к производительности является обязательным, можно использовать следующий метод:

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

Или (для однолинейных фанатов):

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

Хотя последний метод намного более элегантен, первый, безусловно, лучше для производительности.

Для получения дополнительной информации, пожалуйста, обратитесь к этой записи в моем блоге.


0

Для int [] то, что вы сделали, выглядит хорошо для меня. astander в ответ также будет работать хорошо List<int>.


2
Concat также будет работать для List <int>. Вот что хорошо в Concat, он работает на любом IEnumerable <>
Майк Два

0

Для меньших массивов <10000 элементов:

using System.Linq;

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

int[] result = firstArray.ToList().Concat(secondArray.ToList()).toArray();

зачем использовать Linq, когда не нужно ?!
ина

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

Я думаю, что вышеупомянутое решение является более общим и более легким, чем другие, которые я видел здесь. Он более общий, потому что он не ограничивает конкатенацию только для двух массивов и легче, потому что он не использует ни LINQ, ни List.

Обратите внимание, что решение является кратким, и добавленная универсальность не добавляет значительных накладных расходов во время выполнения.


Я бы порекомендовал попытаться найти новые вопросы, или те, у которых еще нет многочисленных ответов, включая один такой же, как у вас.
Эндрю Барбер

Я предложил это решение, потому что я думаю, что оно суммирует то, что хорошо от других. Это было обработано.
дрова

-2

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

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


2
Unionэто не очень хороший способ сделать это, поскольку он неявно вызывает Distinctи удаляет любые дубликаты из объединенной коллекции. Concatнамного лучше, но это уже в оригинальном вопросе.
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]);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.