.NET এ দুটি অ্যারে মার্জ করা হচ্ছে


225

.NET 2.0 এ কি কোনও বিল্ট ইন ফাংশন রয়েছে যা দুটি অ্যারে নেবে এবং সেগুলিকে একটি অ্যারেতে মার্জ করবে?

অ্যারে উভয়ই একই ধরণের। আমি আমার কোড বেসের মধ্যে বহুল ব্যবহৃত ফাংশন থেকে এই অ্যারেগুলি পাচ্ছি এবং অন্য কোনও ফর্ম্যাটে ডেটা ফেরত ফাংশনটি সংশোধন করতে পারি না।

আমি সম্ভব হলে এটি সম্পাদন করার জন্য আমার নিজের ফাংশনটি এড়াতে চাইছি।

উত্তর:


118

আপনি যদি অ্যারেগুলির মধ্যে কোনওটি চালনা করতে পারেন তবে অনুলিপি সম্পাদনের আগে আপনি এটির আকার পরিবর্তন করতে পারেন:

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

এমএসডিএন-তে উপলব্ধ অ্যারে পদ্ধতিগুলিতে আরও


1
.NET 4.0 সম্পর্কে কোন খবর?
শিমি ওয়েটজ্যান্ডলার

4
নোট যেটি Array.Resizeআসলে অ্যারের আকার পরিবর্তন করে না, এটি এটি অনুলিপি করে। এজন্য প্রথম প্যারামিটারটি বাই-রেফ (যার অর্থ সম্ভবত আপনার প্রথম কোডটি সংকলন করবে না)।
কোডসইনচাউস

2
আমি আপনার কোডের প্রথম অংশটি ফেলে দিয়েছি। এটি কোনও সুবিধা দেয় না এবং আইএমও পড়া আরও শক্ত।
কোডসইনচাওস

3
দয়া করে নোট করুন যে অ্যারে.কপির জন্য দ্বিতীয় কোড উদাহরণে পরামিতিগুলির ক্রমটি ভুল। অ্যারে.কপি ব্যবহার করুন (অ্যারে 1, নতুনআরে, 0); পরিবর্তে.
মার্কো বার্চলার

আপনি এটিও করতে পারেন .. তালিকা <বাইট> ফাইনালআরে = নতুন তালিকা <বাইট> (); finalArray.AddRange (বিন্যাস 1); finalArray.AddRange (বিন্যাস 2); ==> finalArray.toArray ();
ক্যাড্রিক বোয়ভিন

448

সি # 3.0 এ আপনি লিনকিউ এর কনক্যাট পদ্ধতিটি সহজেই এটি সম্পাদন করতে ব্যবহার করতে পারেন:

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

সি # ২.০ এ আপনার কাছে সরাসরি কোনও উপায় নেই তবে অ্যারে.কপি সম্ভবত সেরা সমাধান:

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
আমি লিনকিউ বাস্তবায়ন পছন্দ করি। আমার সত্যিই লাফানো এবং শীঘ্রই
লিনিকিউতে উঠতে

1
সমৃদ্ধ, লিনকিউ বাস্তবায়নের সর্বোত্তম অংশটি কেবল সংক্ষিপ্ত নয়, এটি 2.0 সংস্করণের মতোই দক্ষ, কারণ এটি আইএনমেবলের বিরুদ্ধে কাজ করে।
ব্র্যাড উইলসন

এই উত্তরের এই উপায়ে অন্তর্ভুক্ত রয়েছে এবং কিছু মানদণ্ডের ফলাফলও পাওয়া যায়: stackoverflow.com/questions/415291/…
ডেমির

এটি সম্ভবত সবচেয়ে সহজ উপায় তবে এটি বড় অ্যারেগুলির পক্ষে কার্যকর হতে পারে না, যেহেতু কনক্যাট ফোরচ লুপ + ফলন ব্যবহার করে প্রয়োগ করা হয়েছে (রেফারেন্স উত্স দেখুন)। ব্লককপি সহ একটি সমাধান দ্রুত হবে।
টাইগার করুন

1
একটি ছোট মাথা আপ: আপনি যদি সম্মিলিত ফলাফলের মাধ্যমে কেবল পুনরাবৃত্তি করতে চান তবে এটিকে অ্যারেতে রূপান্তর করার দরকার নেই। চূড়ান্ত অপারেশন একটি অ্যারে অনুলিপি করে। আপনি যদি কোনও মূল <<> এর মাধ্যমে পুনরাবৃত্তি করেন তবে এটি করার দরকার নেই। অবশ্যই এটির অ্যারে থাকার যথেষ্ট কারণ থাকতে পারে।
জোনাস

82

লিনকিউ ব্যবহার করুন :

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

মনে রাখবেন, এটি সদৃশগুলি সরিয়ে দেবে। আপনি যদি নকল রাখতে চান তবে কনক্যাট ব্যবহার করুন।


132
সতর্কতা: ইউনিয়ন সদৃশগুলি সরিয়ে ফেলবে।
যোগে

1
@ ইওজি, এসকিউএল এর মতো মনে রাখার মতো সহজ এবং নামকরণটি সেটের তত্ত্বের সাথে সংযুক্ত রয়েছে।
জিবিগিনিউ ওয়াইড্রো

8
যেহেতু এটি সদৃশগুলি সরিয়ে ফেলবে, এটি কখনই সঠিক উত্তর হতে পারে না।
রনি তোভি

1
আমি দেখতে পাচ্ছি সাইমন ইতিমধ্যে ইউনিয়ন এবং বিকল্প প্রস্তাবনার বিষয়টি উল্লেখ করেছিলেন। এ বিষয়ে আরও আলোচনা করার দরকার নেই যেহেতু সাইমন জানে যে তিনি কী উত্তর দিচ্ছেন।
সুধাকর চাবলি

40

আপনি যদি সদৃশগুলি সরাতে না চান তবে এটি ব্যবহার করে দেখুন

লিনকিউ ব্যবহার করুন:

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

11

প্রথমে নিশ্চিত হয়ে নিন যে আপনি নিজেকে প্রশ্নটি জিজ্ঞাসা করেছেন "আমাকে কি এখানে সত্যই অ্যারে ব্যবহার করা উচিত"?

আপনি যদি এমন কিছু নির্মাণ না করেন যেখানে গতি সর্বাধিক গুরুত্বের সাথে থাকে, তবে টাইপ করা তালিকার মতো List<int>সম্ভবত যাওয়ার উপায়। নেটওয়ার্কে স্টাফ পাঠানোর সময় আমি কেবল একবারে অ্যারে ব্যবহার করি বাইট অ্যারেগুলির জন্য। তা ছাড়া আমি কখনই তাদের স্পর্শ করি না।


এখানে বড় +1। নোট করুন যে সেরা অনুশীলন হ'ল List<T>পাবলিক এপিআইগুলিতে প্রকাশ করা এড়ানো : ব্লগস.এমএসএনএন
বি

10

সহজেই লিনকিউ ব্যবহার করা হবে :

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

প্রথমে অ্যারেগুলিকে তালিকায় রূপান্তর করুন এবং সেগুলি মার্জ করুন ... তারপরে কেবল তালিকাটিকে আবার অ্যারে রূপান্তর করুন :)


আপনি সরাসরি অ্যারে ব্যবহার করা হয় না। আপনি তালিকা ব্যবহার করেছেন!
বেহজাদ ইব্রাহিমি

7

আমি মনে করি আপনি এটির জন্য অ্যারে.কপি ব্যবহার করতে পারেন । এটি উত্স সূচক এবং গন্তব্য সূচী নেয় তাই আপনার এক অ্যারেটিকে অন্যটিতে যুক্ত করতে সক্ষম হওয়া উচিত। আপনার যদি কেবলমাত্র একজনকে অপরটিতে সংযুক্ত করার চেয়ে আরও জটিল হতে হয় তবে এটি আপনার পক্ষে সঠিক সরঞ্জাম নাও হতে পারে।


5

ধরে নিচ্ছি গন্তব্য অ্যারের পর্যাপ্ত জায়গা রয়েছে, Array.Copy()কাজ করবে। আপনি একটি List<T>এবং এর .AddRange()পদ্ধতি ব্যবহার করার চেষ্টা করতে পারেন ।


4

ব্যক্তিগতভাবে, আমি আমার নিজস্ব ভাষা এক্সটেনশানগুলি পছন্দ করি, যা আমি দ্রুত প্রোটোটাইপিংয়ের জন্য নিজের ইচ্ছায় যুক্ত বা সরিয়ে ফেলি।

নীচে স্ট্রিং জন্য একটি উদাহরণ।

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

এটি লিনকিউ এবং কনক্যাটের চেয়ে অনেক দ্রুত। তবুও, একটি কাস্টম IEnumerableটাইপ-মোড়ক ব্যবহার করছে যা উত্তীর্ণ অ্যারেগুলির রেফারেন্স / পয়েন্টার সঞ্চয় করে এবং পুরো সংগ্রহের উপরে লুপিংকে অনুমতি দেয় যেমন এটি একটি সাধারণ অ্যারে। (এইচপিসিতে দরকারী, গ্রাফিক্স প্রসেসিং, গ্রাফিক্স রেন্ডার ...)

তোমার গোপন সংকেত:

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 থেকে এই জাতীয় এক্সটেনশানগুলি সংকলন করেছি, প্রচুর ক্রেডিট কোডপ্রজেক্ট এবং 'স্ট্যাকওভারফ্লো' তে সহায়ক লোকের কাছে যাচ্ছে। আমি শীঘ্রই এগুলি প্রকাশ করব এবং লিঙ্কটি এখানে রাখব।


4

প্রত্যেকেরই ইতিমধ্যে তাদের বক্তব্য রয়েছে তবে আমি মনে করি এটি "এক্সটেনশন পদ্ধতি হিসাবে ব্যবহার করুন" পদ্ধতির চেয়ে আরও পঠনযোগ্য:

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

তবে এটি কেবলমাত্র 2 টি অ্যারে একত্রিত করার সময় ব্যবহার করা যেতে পারে।


4

এটিই আমি নিয়ে এসেছি। পরিবর্তনশীল সংখ্যক অ্যারেগুলির জন্য কাজ করে।

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 }

3

একটি বিকল্প হিসাবে এটি উল্লেখ করার জন্য: আপনি যে অ্যারেগুলির সাথে কাজ করছেন তা যদি কোনও প্রাথমিক ধরণের হয় - বুলিয়ান (বুল), চর, এসবাইট, বাইট, ইন্ট 16 (সংক্ষিপ্ত), ইউআইএনটি 16, ইন্ট 32 (ইনট), ইউআইএনটি 32, ইন্টার 64 (দীর্ঘ) ), UInt64, IntPtr, UIntPtr, একক, বা ডাবল - তারপরে আপনি বাফার.ব্লককপি ব্যবহারের চেষ্টা করতে পারেন (বা উচিত?) । বাফার শ্রেণীর জন্য এমএসডিএন পৃষ্ঠা অনুসারে :

এই শ্রেণীর অনুরূপ পদ্ধতির চেয়ে আদিম ধরনের সাধিত জন্য ভাল কর্মক্ষমতা উপলব্ধ System.Array বর্গ।

@ ওয়ানপ এর উত্তর থেকে সি # 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এবং Array.Copy@OwenP ব্যবহৃত, কিন্তু এই দ্রুত (এমনকি শুধুমাত্র সামান্য হলে) হতে হবে।


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

1

অ্যারে.কপিটো ব্যবহার করে এখানে একটি সাধারণ উদাহরণ is আমি মনে করি এটি আপনার প্রশ্নের উত্তর দেয় এবং কপিটো ব্যবহারের একটি উদাহরণ দেয় - যখন এই ফাংশনটি ব্যবহার করার দরকার হয় তখন আমি সর্বদা বিস্মিত হই কারণ সহায়তাটি কিছুটা অস্পষ্ট - যেখানে সন্নিবেশ ঘটানো হয় সেখানে সূচকটি গন্তব্য অ্যারেতে অবস্থিত।

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

আমার ধারণা আপনি এটি এত সহজ পেতে পারেন না।


1

অজানা সংখ্যক অ্যারে সংযুক্ত করার জন্য আমার একটি সমাধান দরকার।

অবাক কেউ কিছু আর ব্যবহার করে একটি সমাধান প্রদান করা SelectManyসঙ্গে params

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

আপনি যদি স্বতন্ত্র আইটেমগুলি না চান তবে কেবল স্বতন্ত্র সরান।

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

দ্রষ্টব্য: স্বতন্ত্র ব্যবহার করার সময় অবশ্যই অর্ডার দেওয়ার কোনও গ্যারান্টি নেই।


0

আমি ধরে নিচ্ছি যে আপনি বিল্ট-ইন। নেট অ্যারেগুলির বিপরীতে আপনার নিজের অ্যারে প্রকারগুলি ব্যবহার করছেন:

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

এটি করার আর একটি উপায় হ'ল অ্যারেলিস্ট শ্রেণিতে অন্তর্নির্মিত ব্যবহার করা।

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

উভয় উদাহরণ সি #।


0
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 + " ");  

উপরের কোডটি ব্যবহার করে দুটি অ্যারে সহজেই একত্রিত হতে পারে।


0

নাল হ্যান্ডেল করার জন্য তৈরি এবং এক্সটেনশন পদ্ধতি

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

0

আপনি একটি অ্যারের নিজেই আপনি ব্যবহার করতে পারেন উৎস অ্যারে যদি SelectMany :

var arrays = new[]{new[]{1, 2, 3}, new[]{4, 5, 6}};
var combined = arrays.SelectMany(a => a).ToArray();
foreach (var v in combined) Console.WriteLine(v);   

দেয়

1
2
3
4
5
6

সম্ভবত এটি দ্রুততম পদ্ধতি নয় তবে এটি ইউজকেসের উপর নির্ভর করে ফিট করতে পারে।


-1

এই কোডটি সকল ক্ষেত্রে কাজ করবে:

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

আপনি যে সমাধানটি সরবরাহ করেন সে সম্পর্কে আরও বিবরণ যোগ করতে পারেন?
অ্যাবারিসোন

1
যদিও এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না।
gunr2171

এটি একটি বাছাই করা মার্জ বলে মনে হয়, যা নিজের নিজের ক্ষেত্রে (মূলত মার্জসার্ট পুনরাবৃত্ত কৌশলের অংশ হিসাবে) কার্যকর হয়ে ওপি যা চেয়েছিল তার চেয়ে বেশি হতে পারে।
ড্যারেল হফম্যান

এই সমাধানটি কাজ করার সময়, সি # এবং ভিবি.নেট চালু হওয়ার পরে প্রচুর কৌশল অবলম্বন করা লোকেরা এ জাতীয় সমাধান পছন্দ করতে পারে না।
সুধাকর চাবলি

-2

এটা চেষ্টা কর:

ArrayLIst al = new ArrayList();
al.AddRange(array_1);
al.AddRange(array_2);
al.AddRange(array_3);
array_4 = al.ToArray();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.