.NET 2.0 には、2 つの配列を取り、それらを 1 つの配列にマージする組み込み関数がありますか?
配列は両方とも同じ型です。コード ベース内で広く使用されている関数からこれらの配列を取得していますが、関数を変更してデータを別の形式で返すことはできません。
可能であれば、これを達成するために独自の関数を作成しないようにしています。
C# 3.0 では、LINQ のConcatメソッドを使用してこれを簡単に実現できます。
int[] front = { 1, 2, 3, 4 };
int[] back = { 5, 6, 7, 8 };
int[] combined = front.Concat(back).ToArray();
C# 2.0 では、このような直接的な方法はありませんが、おそらく Array.Copy が最適なソリューションです。
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);
これは、独自のバージョンの を実装するために簡単に使用できますConcat
。
配列の 1 つを操作できる場合は、コピーを実行する前にサイズを変更できます。
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);
それ以外の場合は、新しい配列を作成できます
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);
LINQを使用します。
var arr1 = new[] { 1, 2, 3, 4, 5 };
var arr2 = new[] { 6, 7, 8, 9, 0 };
var arr = arr1.Union(arr2).ToArray();
これにより、重複が削除されることに注意してください。重複を保持したい場合は、Concat を使用します。
重複を削除したくない場合は、これを試してください
LINQ を使用します。
var arr1 = new[] { 1, 2, 3, 4, 5 };
var arr2 = new[] { 6, 7, 8, 9, 0 };
var arr = arr1.Concat(arr2).ToArray();
まず、「本当にここで配列を使用する必要があるのか」という質問を自問してください。
速度が最も重要な何かを構築している場合を除き、型付きリストのようなものを使用List<int>
するのがおそらく道です。私が配列を使用するのは、ネットワーク経由でデータを送信するときのバイト配列だけです。それ以外は一切触りません。
これにはArray.Copyを使用できると思います。ソース インデックスと宛先インデックスを使用するため、ある配列を別の配列に追加できるはずです。一方をもう一方に追加するだけでなく、より複雑にする必要がある場合、これは適切なツールではない可能性があります。
誰もがすでに意見を述べていますが、これは「拡張メソッドとして使用する」アプローチよりも読みやすいと思います。
var arr1 = new[] { 1, 2, 3, 4, 5 };
var arr2 = new[] { 6, 7, 8, 9, 0 };
var arr = Queryable.Concat(arr1, arr2).ToArray();
ただし、2 つのアレイをまとめる場合にのみ使用できます。
宛先配列に十分なスペースがあると仮定すると、機能しArray.Copy()
ます。List<T>
aとその.AddRange()
メソッドを使用することもできます。
個人的には、ラピッド プロトタイピングのために自由に追加または削除する独自の言語拡張機能を好みます。
以下は文字列の例です。
//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;
}
}
LINQ や Concat よりもはるかに高速です。IEnumerable
さらに高速なのは、渡された配列の参照/ポインターを格納し、通常の配列であるかのようにコレクション全体をループできるカスタム Type-wrapper を使用することです。(HPC、グラフィックス処理、グラフィックス レンダリングで役立ちます...)
あなたのコード:
var someStringArray = new[]{"a", "b", "c"};
var someStringArray2 = new[]{"d", "e", "f"};
someStringArray.Append(someStringArray2 ); //contains a,b,c,d,e,f
コード全体とジェネリック バージョンについては、https ://gist.github.com/lsauer/7919764 を参照してください。
注:これは、拡張されていない IEnumerable オブジェクトを返します。拡張オブジェクトを返すのは少し遅くなります。
私は 2002 年以来、このような拡張機能をコンパイルしており、CodeProject と 'Stackoverflow' で役立つ人々に多くの功績を残しています。私はこれらをすぐにリリースし、ここにリンクを張ります.
オプションとしてメモしておくと、使用している配列がプリミティブ型の場合 – Boolean (bool)、Char、SByte、Byte、Int16 (short)、UInt16、Int32 (int)、UInt32、Int64 (long) )、UInt64、IntPtr、UIntPtr、Single、または Double – Buffer.BlockCopyを使用することができます (またはすべきでしょうか?) 。Bufferクラスの MSDN ページによると:
このクラスは、 System.Arrayクラスの同様のメソッドよりもプリミティブ型を操作するパフォーマンスが向上します。
@OwenP の回答の C# 2.0 の例を出発点として使用すると、次のように機能します。
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);
Buffer.BlockCopy
@OwenP が使用した と の間に構文の違いはほとんどありませんArray.Copy
が、これは (ほんの少しでも) 高速になるはずです。
他の誰かが 2 つの画像バイト配列をマージする方法を探している場合:
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;
}
Array.CopyTo を使用した簡単な例を次に示します。それはあなたの質問に答え、CopyTo の使用例を示していると思います - ヘルプが少し不明確であるため、この関数を使用する必要があるときはいつも困惑しています - インデックスは、挿入が行われる宛先配列内の位置です。
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);
これ以上単純なことはできないと思います。
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 + " ");
上記のコードを使用すると、2 つの配列を簡単にマージできます。
組み込みの .NET 配列ではなく、独自の配列型を使用していると仮定しています。
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;
}
これを行う別の方法は、組み込みの 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;
}
どちらの例も C# です。
このコードは、すべてのケースで機能します。
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--];
}
}
Try this:
ArrayLIst al = new ArrayList();
al.AddRange(array_1);
al.AddRange(array_2);
al.AddRange(array_3);
array_4 = al.ToArray();