Pergunta

Há um construído em função de .NET 2.0 que terá duas matrizes e fundi-los em um array?

As matrizes são ambos do mesmo tipo.Eu estou ficando estas matrizes a partir de uma amplamente utilizado função dentro da minha base de código e não pode modificar a função para retornar os dados em um formato diferente.

Eu estou olhando para evitar escrever minha própria função para realizar esta se possível.

Foi útil?

Solução

Se você pode manipular matrizes, você pode redimensioná-lo antes de executar a cópia:

T[] array1 = getOneArray();
T[] array2 = getAnotherArray();
int array1OriginalLength = array1.Length;
Array.Resize<T>(ref array1, array1OriginalLength + array2.Length);
Array.Copy(array2, 0, array1, array1OriginalLength, array2.Length);

Caso contrário, você pode criar uma nova matriz

T[] array1 = getOneArray();
T[] array2 = getAnotherArray();
T[] newArray = new T[array1.Length + array2.Length];
Array.Copy(array1, newArray, array1.Length);
Array.Copy(array2, 0, newArray, array1.Length, array2.Length);

Mais disponível Matriz de métodos no MSDN.

Outras dicas

No C# 3.0, você pode usar o LINQ Concat método para fazer isso facilmente:

int[] front = { 1, 2, 3, 4 };
int[] back = { 5, 6, 7, 8 };
int[] combined = front.Concat(back).ToArray();

Em C# 2.0, você não tem essa de uma forma direta, mas de Matriz.Copiar é, provavelmente, a melhor solução:

int[] front = { 1, 2, 3, 4 };
int[] back = { 5, 6, 7, 8 };

int[] combined = new int[front.Length + back.Length];
Array.Copy(front, combined, front.Length);
Array.Copy(back, 0, combined, front.Length, back.Length);

Isso poderia facilmente ser utilizada para implementar a sua própria versão de Concat.

Utilização LINQ:

var arr1 = new[] { 1, 2, 3, 4, 5 };
var arr2 = new[] { 6, 7, 8, 9, 0 };
var arr = arr1.Union(arr2).ToArray();

Tenha em mente que isto irá remover duplicatas.Se você deseja manter duplicatas, use Concat.

Se você não deseja remover duplicatas, em seguida, tente esta

Usar o LINQ:

var arr1 = new[] { 1, 2, 3, 4, 5 };
var arr2 = new[] { 6, 7, 8, 9, 0 };
var arr = arr1.Concat(arr2).ToArray();

Primeiro, certifique-se de que você pergunte a si mesmo: "eu devo realmente estar usando uma Matriz aqui?".

A menos que você está construindo algo, onde a velocidade é de suma importância, um tipo de Lista, como List<int> é, provavelmente, o caminho a percorrer.A única vez que eu sempre uso matrizes são para matrizes de bytes quando o envio de material através da rede.Que isso, eu nunca tocá-los.

Mais fácil seria apenas usando LINQ:

var array = new string[] { "test" }.ToList();
var array1 = new string[] { "test" }.ToList();
array.AddRange(array1);
var result = array.ToArray();

Primeiro converter as matrizes e listas de mala-los...Depois é só converter a lista para uma matriz :)

Eu acho que você pode usar Matriz.Cópia para este.É preciso uma fonte de índice e índice de destino, então você deve ser capaz de acrescentar uma matriz para o outro.Se você precisa ir mais complexo do que apenas acrescentar um para o outro, isso não pode ser a ferramenta certa para você.

Supondo que a matriz de destino tem espaço suficiente, Array.Copy() irá trabalhar.Você também pode tentar usar um List<T> e o seu .AddRange() o método.

Pessoalmente, eu prefiro a minha própria Extensões de Linguagem, o que eu adicionar ou remover à vontade para prototipagem rápida.

A seguir está um exemplo para seqüências de caracteres.

//resides in IEnumerableStringExtensions.cs
public static class IEnumerableStringExtensions
{
   public static IEnumerable<string> Append(this string[] arrayInitial, string[] arrayToAppend)
   {
       string[] ret = new string[arrayInitial.Length + arrayToAppend.Length];
       arrayInitial.CopyTo(ret, 0);
       arrayToAppend.CopyTo(ret, arrayInitial.Length);

       return ret;
   }
}

É muito mais rápido do que o LINQ e o Concat.Mais rápido ainda, é usar um personalizado IEnumerable Tipo-wrapper que armazena referências/ponteiros do passado matrizes e permite que um loop através da coleção inteira como se fosse uma matriz normal.(Útil em HPC, de Processamento de elementos Gráficos, Gráficos de compor...)

O Seu Código:

var someStringArray = new[]{"a", "b", "c"};
var someStringArray2 = new[]{"d", "e", "f"};
someStringArray.Append(someStringArray2 ); //contains a,b,c,d,e,f

Para o código inteiro e um genéricos versão consulte: https://gist.github.com/lsauer/7919764

Nota: Isso retorna um ampliada objeto IEnumerable.Para retornar um objeto estendido é um pouco mais lento.

Eu compilei tais extensões, desde 2002, com um monte de créditos de ir para pessoas úteis no CodeProject e 'Stackoverflow'.Vou liberar estes pouco e colocar o link para aqui.

Todo mundo já teve uma palavra a dizer, mas eu acho que esta mais legível do que o "uso como método de Extensão" abordagem:

var arr1 = new[] { 1, 2, 3, 4, 5 };
var arr2 = new[] { 6, 7, 8, 9, 0 };
var arr = Queryable.Concat(arr1, arr2).ToArray();

No entanto, ele só pode ser usado quando reunimos 2 matrizes.

No caso de alguém está olhando para a forma como a mesclagem de duas imagens matrizes de bytes:

        private void LoadImage()
        {
            string src = string.empty;
            byte[] mergedImageData = new byte[0];

            mergedImageData = MergeTwoImageByteArrays(watermarkByteArray, backgroundImageByteArray);
            src = "data:image/png;base64," + Convert.ToBase64String(mergedImageData);
            MyImage.ImageUrl = src;
        }

        private byte[] MergeTwoImageByteArrays(byte[] imageBytes, byte[] imageBaseBytes)
        {
            byte[] mergedImageData = new byte[0];
            using (var msBase = new MemoryStream(imageBaseBytes))
            {
                System.Drawing.Image imgBase = System.Drawing.Image.FromStream(msBase);
                Graphics gBase = Graphics.FromImage(imgBase);
                using (var msInfo = new MemoryStream(imageBytes))
                {
                    System.Drawing.Image imgInfo = System.Drawing.Image.FromStream(msInfo);
                    Graphics gInfo = Graphics.FromImage(imgInfo);
                    gBase.DrawImage(imgInfo, new Point(0, 0));
                    //imgBase.Save(Server.MapPath("_____testImg.png"), ImageFormat.Png);
                    MemoryStream mergedImageStream = new MemoryStream();
                    imgBase.Save(mergedImageStream, ImageFormat.Png);
                    mergedImageData = mergedImageStream.ToArray();
                    mergedImageStream.Close();
                }
            }
            return mergedImageData;
        }

Apenas para tê-lo indicado como uma opção:se as matrizes estão trabalhando com você, são de um tipo primitivo, Booleanos (bool), Char, SByte, Byte, Int16 (curto), UInt16, Int32 (int), UInt32, Int64 (longo), UInt64, IntPtr, UIntPtr, Simples ou Duplo, em seguida, você pode (ou deve?) tente usar Buffer.BlockCopy.De acordo com a página da MSDN para o Memória intermédia classe:

Essa classe fornece um melhor desempenho para a manipulação de tipos primitivos do que métodos semelhantes no Do sistema.Matriz de classe.

Utilizando o C# 2.0 exemplo do @OwenP do responder como um ponto de partida, funcionaria da seguinte forma:

int[] front = { 1, 2, 3, 4 };
int[] back = { 5, 6, 7, 8 };

int[] combined = new int[front.Length + back.Length];
Buffer.BlockCopy(front, 0, combined, 0, front.Length);
Buffer.BlockCopy(back, 0, combined, front.Length, back.Length);

Não há quase nenhuma diferença de sintaxe entre Buffer.BlockCopy e o Array.Copy que @OwenP usado, mas isso deve ser mais rápido (mesmo que só um pouco).

Aqui está um exemplo simples usando a Matriz.CopyTo.Eu acho que isso responde a sua pergunta e dá um exemplo de CopyTo de uso - sempre fico intrigado quando eu preciso para utilizar esta função, porque a ajuda é um pouco confusa - o índice é a posição na matriz de destino onde a inserção ocorre.

int[] xSrc1 = new int[3] { 0, 1, 2 };
int[] xSrc2 = new int[5] { 3, 4, 5, 6 , 7 };

int[] xAll = new int[xSrc1.Length + xSrc2.Length];
xSrc1.CopyTo(xAll, 0);
xSrc2.CopyTo(xAll, xSrc1.Length);

Eu acho que você não pode obtê-lo muito mais simples.

Eu precisava de uma solução para combinar um número desconhecido de matrizes.

Surpreendeu ninguém forneceu uma solução usando SelectMany com params.

 private static T[] Combine<T>(params IEnumerable<T>[] items) =>
                    items.SelectMany(i => i).Distinct().ToArray();

Se você não quiser itens distintos apenas remover distintos.

 public string[] Reds = new [] { "Red", "Crimson", "TrafficLightRed" };
 public string[] Greens = new [] { "Green", "LimeGreen" };
 public string[] Blues = new [] { "Blue", "SkyBlue", "Navy" };

 public string[] Colors = Combine(Reds, Greens, Blues);

Nota:Definitivamente há nenhuma garantia de pedido quando usando distintos.

É isso que eu vim acima com.Funciona por um número variável de matrizes.

public static T[] ConcatArrays<T>(params T[][] args)
    {
        if (args == null)
            throw new ArgumentNullException();

        var offset = 0;
        var newLength = args.Sum(arr => arr.Length); 
        var newArray = new T[newLength];

        foreach (var arr in args)
        {
            Buffer.BlockCopy(arr, 0, newArray, offset, arr.Length);
            offset += arr.Length;
        }

        return newArray;
    }

...

var header = new byte[] { 0, 1, 2};
var data = new byte[] { 3, 4, 5, 6 };
var checksum = new byte[] {7, 0};
var newArray = ConcatArrays(header, data, checksum);
//output byte[9] { 0, 1, 2, 3, 4, 5, 6, 7, 0 }

Eu estou supondo que você está usando os seus próprios tipos de matriz em oposição ao built-in .NET matrizes:

public string[] merge(input1, input2)
{
    string[] output = new string[input1.length + input2.length];
    for(int i = 0; i < output.length; i++)
    {
        if (i >= input1.length)
            output[i] = input2[i-input1.length];
        else
            output[i] = input1[i];
    }
    return output;
}

Outra maneira de fazer isso seria usando o construído em classe ArrayList.

public ArrayList merge(input1, input2)
{
    Arraylist output = new ArrayList();
    foreach(string val in input1)
        output.add(val);
    foreach(string val in input2)
        output.add(val);
    return output;
}

Ambos os exemplos são C#.

int [] SouceArray1 = new int[] {2,1,3};
int [] SourceArray2 = new int[] {4,5,6};
int [] targetArray = new int [SouceArray1.Length + SourceArray2.Length];
SouceArray1.CopyTo(targetArray,0);
SourceArray2.CopyTo(targetArray,SouceArray1.Length) ; 
foreach (int i in targetArray) Console.WriteLine(i + " ");  

Usando o código acima duas Matrizes podem ser facilmente fundidos.

Criado e o método de extensão para processar null

public static class IEnumerableExtenions
{
    public static IEnumerable<T> UnionIfNotNull<T>(this IEnumerable<T> list1, IEnumerable<T> list2)
    {
        if (list1 != null && list2 != null)
            return list1.Union(list2);
        else if (list1 != null)
            return list1;
        else if (list2 != null)
            return list2;
        else return null;
    }
}

Este código irá funcionar para todos os casos:

int[] a1 ={3,4,5,6};
int[] a2 = {4,7,9};
int i = a1.Length-1;
int j = a2.Length-1;
int resultIndex=  i+j+1;
Array.Resize(ref a2, a1.Length +a2.Length);
while(resultIndex >=0)
{
    if(i != 0 && j !=0)
    {
        if(a1[i] > a2[j])
        {
            a2[resultIndex--] = a[i--];
        }
        else
        {
            a2[resultIndex--] = a[j--];
        }
    }
    else if(i>=0 && j<=0)
    { 
        a2[resultIndex--] = a[i--];
    }
    else if(j>=0 && i <=0)
    {
       a2[resultIndex--] = a[j--];
    }
}

Tente isso:

ArrayLIst al = new ArrayList();
al.AddRange(array_1);
al.AddRange(array_2);
al.AddRange(array_3);
array_4 = al.ToArray();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top