সি # তে দুটি বা আরও বেশি বাইট অ্যারে একত্রিত করার সর্বোত্তম উপায়


238

আমার # সিতে 3 বাইট অ্যারে রয়েছে যা আমাকে একটিতে একত্রিত করতে হবে। এই কাজটি সম্পন্ন করার সবচেয়ে দক্ষ পদ্ধতি কী হবে?


3
আপনার প্রয়োজনীয়তা বিশেষত কি? আপনি কি অ্যারের ইউনিয়ন নিচ্ছেন বা আপনি একই মানের একাধিক উদাহরণ সংরক্ষণ করছেন? আপনি কি আইটেমগুলি বাছাই করতে চান বা আপনি প্রাথমিক অ্যারেগুলিতে ক্রম সংরক্ষণ করতে চান? আপনি কি গতিতে বা কোডের লাইনে দক্ষতার সন্ধান করছেন?
জেসন

এটি পছন্দ করুন, "সেরা" আপনার প্রয়োজনীয়তাগুলি নির্ভর করে।
অ্যাডি

7
আপনি যদি লিনকিউ ব্যবহার করতে সক্ষম হন তবে আপনি কেবল এই Concatপদ্ধতিটি ব্যবহার করতে পারেন :IEnumerable<byte> arrays = array1.Concat(array2).Concat(array3);
ক্যাস্পার একটি

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

উত্তর:


326

আদিম ধরণের (বাইট সহ) জন্য, System.Buffer.BlockCopyপরিবর্তে ব্যবহার করুন System.Array.Copy। এটি দ্রুত।

আমি প্রস্তাবিত প্রতিটি পদ্ধতির প্রত্যেককে 10 টি বাইটের 3 অ্যারে ব্যবহার করে 1 মিলিয়ন বার লুপে নির্বাহ করি। ফলাফল এখানে:

  1. নতুন বাইট অ্যারে ব্যবহার করে System.Array.Copy - 0.2187556 সেকেন্ড
  2. নতুন বাইট অ্যারে ব্যবহার করে System.Buffer.BlockCopy - 0.1406286 সেকেন্ড
  3. অনুমিত <বিটেট> সি # ফলন অপারেটর ব্যবহার করে - 0.0781270 সেকেন্ড
  4. লিনিউ এর কনক্যাট <> - 0.0781270 সেকেন্ড ব্যবহার করে অনুমিত <বিটেট>

আমি প্রতিটি অ্যারের আকার 100 টি উপাদান করে বাড়িয়ে পরীক্ষাটি আবার চালিয়েছি:

  1. নতুন বাইট অ্যারে ব্যবহার করে System.Array.Copy - 0.2812554 সেকেন্ড
  2. নতুন বাইট অ্যারে ব্যবহার করে System.Buffer.BlockCopy - 0.2500048 সেকেন্ড
  3. অনুমিত <বিটেট> সি # ফলন অপারেটর ব্যবহার করে - 0.0625012 সেকেন্ড
  4. লিনকু কনক্যাট <> - 0.0781265 সেকেন্ড ব্যবহার করে অনুমিত <বিটেট>

আমি প্রতিটি অ্যারের আকার 1000 উপাদানগুলিতে বাড়িয়েছি এবং আবার পরীক্ষা চালিয়েছি:

  1. নতুন বাইট অ্যারে ব্যবহার করে System.Array.Copy - 1.0781457 সেকেন্ড
  2. নতুন বাইট অ্যারে ব্যবহার করে System.Buffer.BlockCopy - 1.0156445 সেকেন্ড
  3. অনুমিত <বিটেট> সি # ফলন অপারেটর ব্যবহার করে - 0.0625012 সেকেন্ড
  4. লিনকু কনক্যাট <> - 0.0781265 সেকেন্ড ব্যবহার করে অনুমিত <বিটেট>

অবশেষে, আমি প্রতিটি অ্যারের আকার 1 মিলিয়নে বাড়িয়েছি এবং পরীক্ষাটি আবার চালিয়েছি, প্রতিটি লুপকে কেবল 4000 বার কার্যকর করে :

  1. নতুন বাইট অ্যারে ব্যবহার করে System.Array.Copy - 13.4533833 সেকেন্ড
  2. নতুন বাইট অ্যারে ব্যবহার করে System.Buffer.BlockCopy - 13.1096267 সেকেন্ড
  3. অনুমিত <বিটেট> সি # ফলন অপারেটর ব্যবহার করে - 0 সেকেন্ড
  4. লিনিউ এর কনক্যাট <> - 0 সেকেন্ড ব্যবহার করে অনুমিত <বিটেট>

সুতরাং, আপনার যদি নতুন বাইট অ্যারে প্রয়োজন হয় তবে ব্যবহার করুন

byte[] rv = new byte[a1.Length + a2.Length + a3.Length];
System.Buffer.BlockCopy(a1, 0, rv, 0, a1.Length);
System.Buffer.BlockCopy(a2, 0, rv, a1.Length, a2.Length);
System.Buffer.BlockCopy(a3, 0, rv, a1.Length + a2.Length, a3.Length);

কিন্তু, যদি আপনি একটি ব্যবহার করতে পারেন IEnumerable<byte>, স্পষ্টভাবে LINQ এর CONCAT <> পদ্ধতি পছন্দ করে। এটি সি # ফলন অপারেটরের চেয়ে সামান্য ধীর, তবে আরও সংক্ষিপ্ত এবং আরও মার্জিত।

IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);

আপনার যদি স্বেচ্ছাসেবী সংখ্যক অ্যারে থাকে এবং .NET 3.5 ব্যবহার করা হয় তবে আপনি System.Buffer.BlockCopyসমাধানটিকে আরও সাধারণভাবে তৈরি করতে পারেন :

private byte[] Combine(params byte[][] arrays)
{
    byte[] rv = new byte[arrays.Sum(a => a.Length)];
    int offset = 0;
    foreach (byte[] array in arrays) {
        System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
        offset += array.Length;
    }
    return rv;
}

* দ্রষ্টব্য: উপরের ব্লকটির কাজ করার জন্য আপনাকে নীচের অংশে নীচের নেমস্পেস যুক্ত করতে হবে।

using System.Linq;

পরবর্তী ডেটা স্ট্রাকচারের পুনরাবৃত্তির বিষয়ে জন স্কিটির বক্তব্যটি (বাইট অ্যারে বনাম আইয়ুনিউরেবল <বিট>), আমি শেষ টাইমিং টেস্টটি পুনরায় চালিয়েছি (1 মিলিয়ন উপাদান, 4000 পুনরাবৃত্তি) প্রতিটিটির সাথে পুরো অ্যারের উপরে পুনরাবৃত্তি করে এমন একটি লুপ যুক্ত করেছি পাস:

  1. নতুন বাইট অ্যারে ব্যবহার করে System.Array.Copy - 78.20550510 সেকেন্ড
  2. নতুন বাইট অ্যারে ব্যবহার করে System.Buffer.BlockCopy - 77.89261900 সেকেন্ড
  3. অনুমিত <বিটেট> সি # ফলন অপারেটর ব্যবহার করে - 551.7150161 সেকেন্ড
  4. লিনিউ এর কনক্যাট <> - 448.1804799 সেকেন্ড ব্যবহার করে অনুমিত <বিটেট>

মুল বক্তব্যটি হ'ল, উভয় তৈরি এবং ফলস্বরূপ ডেটা স্ট্রাকচারের দক্ষতা বোঝা খুব গুরুত্বপূর্ণ । কেবল সৃষ্টির দক্ষতার উপর ফোকাস করা ব্যবহারের সাথে সম্পর্কিত অদক্ষতা উপেক্ষা করতে পারে। কুডোস, জোন


61
তবে আপনি কি আসলে এটিকে শেষে একটি অ্যারেতে রূপান্তর করছেন, যেমন প্রশ্নটি প্রয়োজন? যদি তা না হয় তবে অবশ্যই এটি দ্রুত - তবে এটি প্রয়োজনীয়তা পূরণ করছে না।
জন স্কিটি

18
পুনরায়: ম্যাট ডেভিস - আপনার "প্রয়োজনীয়তাগুলি" আইউনামারেবলকে অ্যারে রূপান্তরিত করে কিনা তা বিবেচ্য নয় - আপনার প্রয়োজনীয়তার যা যা প্রয়োজন তা হ'ল ফলাফলটি কিছুটা ফেরে ব্যবহৃত হয় । আইএননামেবলের উপর আপনার পারফরম্যান্স পরীক্ষাগুলি যেহেতু খুব কম, কারণ আপনি আসলে কিছু করছেন না ! আপনি ফলাফলগুলি ব্যবহার করার চেষ্টা না করা অবধি LINQ এর কোনও কাজ সম্পাদন করে না। এই কারণে আমি আপনার উত্তরটি বস্তুনিষ্ঠভাবে ভুল বলে মনে করি এবং অন্যদের লিনকিউ ব্যবহার করতে নেতৃত্ব দিতে পারি যখন তারা পারফরম্যান্সের বিষয়ে চিন্তা না করে তাদের একেবারে উচিত নয়।
csauve

12
আমি আপনার আপডেট সহ পুরো উত্তরটি পড়েছি, আমার মন্তব্য দাঁড়িয়েছে। আমি জানি আমি দেরিতে দলে যোগ দিচ্ছি, তবে উত্তরটি গুরুতর বিভ্রান্তিকর এবং প্রথমার্ধটি স্পষ্টতই মিথ্যা
csauve

14
যে উত্তরটিতে ভুয়া এবং বিভ্রান্তিমূলক তথ্য রয়েছে তার উত্তরে কেন শীর্ষ ভোটের উত্তর দেওয়া হয়েছে এবং কারও (জন স্কিটি) এটি ওপিএস প্রশ্নের উত্তর দেয়নি বলে উল্লেখ করার পরেও মূলত এটির মূল বিবরণটিকে সম্পূর্ণরূপে বাতিল করতে সম্পাদনা করা হয়েছিল ?
মিঃসিসি

3
বিভ্রান্তিকর উত্তর। এমনকি সংস্করণটি প্রশ্নের উত্তর দিচ্ছে না।
সার্জ প্রোফাইলেসবুক

154

অনেক উত্তর আমার কাছে বর্ণিত প্রয়োজনীয়তা উপেক্ষা করছে বলে মনে হচ্ছে:

  • ফলাফলটি বাইট অ্যারে হওয়া উচিত
  • এটি যথাসম্ভব দক্ষ হওয়া উচিত

এই দু'জনে মিলে একটি লাইনকিউ সিকোয়েন্সকে বাইটস থেকে বের করে দেয় - এর সাথে yieldযে কোনও কিছুই পুরো ক্রমটি না ঘটিয়ে চূড়ান্ত আকারটি অর্জন করা অসম্ভব করে দেয়।

সেই না হন, তাহলে বাস্তব কোর্সের প্রয়োজনীয়তা LINQ একটি পুরোপুরি ভালো সমাধান (অথবা হতে পারে IList<T>বাস্তবায়ন)। তবে, আমি ধরে নেব যে সুপারডামবেল জানেন তিনি কী চান।

(সম্পাদনা: আমার আরও একটি ধারণা ছিল। অ্যারের অনুলিপি তৈরি করা এবং অলসভাবে সেগুলি পড়ার মধ্যে একটি বড় শব্দার্থক পার্থক্য রয়েছে calling কল করার পরে আপনি যদি কোনও "উত্স" অ্যারে ডেটা পরিবর্তন করেন তবে কী ঘটবে তা বিবেচনা করুন Combineঘটছে।। (অথবা যাই হোক না কেন ) পদ্ধতি তবে ফলাফলটি ব্যবহারের আগে - অলস মূল্যায়নের সাথে, সেই পরিবর্তনটি দৃশ্যমান হবে an তাত্ক্ষণিক অনুলিপি সহ, এটি হবে না Dif বিভিন্ন পরিস্থিতিতে বিভিন্ন আচরণের জন্য আহ্বান জানানো হবে - সচেতন হওয়ার জন্য কেবল কিছু))

এখানে আমার প্রস্তাবিত পদ্ধতিগুলি রয়েছে - যা অন্যান্য উত্তরগুলির সাথে সামঞ্জস্যপূর্ণ, অবশ্যই :)

public static byte[] Combine(byte[] first, byte[] second)
{
    byte[] ret = new byte[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

public static byte[] Combine(byte[] first, byte[] second, byte[] third)
{
    byte[] ret = new byte[first.Length + second.Length + third.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                     third.Length);
    return ret;
}

public static byte[] Combine(params byte[][] arrays)
{
    byte[] ret = new byte[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (byte[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

অবশ্যই "প্যারামগুলি" সংস্করণটির জন্য প্রথমে বাইট অ্যারেগুলির একটি অ্যারে তৈরি করা দরকার যা অতিরিক্ত অদক্ষতার পরিচয় দেয়।


জন, আপনি কী বলছেন তা আমি ঠিক বুঝতে পেরেছি। আমার একমাত্র বক্তব্য যে কখনও কখনও অন্যান্য সমাধানের অস্তিত্ব উপলব্ধি না করেই ইতিমধ্যে ইতিমধ্যে একটি নির্দিষ্ট বাস্তবায়ন নিয়ে প্রশ্ন করা হয়। বিকল্প প্রস্তাব না দিয়ে কেবল উত্তর সরবরাহ করা আমার কাছে বিরক্তির মতো মনে হয়। থটস?
ম্যাট ডেভিস

1
@ ম্যাট: হ্যাঁ, বিকল্প প্রস্তাব দেওয়া ভাল - তবে এটি ব্যাখ্যা করা উচিত যে তারা জিজ্ঞাসা করা প্রশ্নের উত্তর হিসাবে সরে যাওয়ার পরিবর্তে বিকল্প ছিল are (আমি বলছি না যে আপনি এটি করেছিলেন - আপনার উত্তরটি খুব ভাল))
জন স্কিটি

4
(যদিও আমি মনে করি যে আপনার পারফরম্যান্সের মানদণ্ডে অলস মূল্যায়নকে অন্যায্য সুবিধা দেওয়া এড়াতে প্রতিটি ক্ষেত্রে সমস্ত ফলাফলের জন্য সময় নেওয়া উচিত))
জন স্কিটি

1
এমনকি "ফলাফল অবশ্যই একটি অ্যারে হতে হবে" এর প্রয়োজনীয়তা পূরণ না করেই কেবল "ফলাফলটি কিছুটা ক্ষেত্রে ব্যবহার করতে হবে" এর প্রয়োজনীয়তার সাথে মিলিত হওয়া লিনকিউটিকে অপ-অনুকূল করে তোলে। আমি মনে করি যে ফলাফলটি ব্যবহার করতে সক্ষম হওয়ার প্রয়োজনটি অন্তর্ভুক্ত হওয়া উচিত!
csauve

2
@ অ্যান্ডলিয়ার: অন্য যে কোনও কিছু বাদে, বাফার.ব্লককপি কেবলমাত্র প্রাথমিক প্রকারের সাথে কাজ করে।
জন স্কিটি

44

কোড পরিষ্কারের জন্য আমি ম্যাটসের লিনকিউ উদাহরণটি আরও একধাপ এগিয়ে নিয়েছি:

byte[] rv = a1.Concat(a2).Concat(a3).ToArray();

আমার ক্ষেত্রে, অ্যারেগুলি ছোট, তাই আমি পারফরম্যান্স সম্পর্কে উদ্বিগ্ন নই।


3
সংক্ষিপ্ত এবং সহজ সমাধান, একটি পারফরম্যান্স পরীক্ষা দুর্দান্ত হবে!
সেবাস্তিয়ান

3
এটি অবশ্যই স্পষ্ট, পঠনযোগ্য, কোনও বাহ্যিক গ্রন্থাগার / সহায়তাকারী প্রয়োজন নেই, এবং বিকাশের সময়ের নিরিখে এটি বেশ দক্ষ। রান-টাইম পারফরম্যান্স সমালোচিত না হলে দুর্দান্ত।
বিনকি

28

আপনার যদি কেবল নতুন বাইট অ্যারে প্রয়োজন হয় তবে নিম্নলিখিতগুলি ব্যবহার করুন:

byte[] Combine(byte[] a1, byte[] a2, byte[] a3)
{
    byte[] ret = new byte[a1.Length + a2.Length + a3.Length];
    Array.Copy(a1, 0, ret, 0, a1.Length);
    Array.Copy(a2, 0, ret, a1.Length, a2.Length);
    Array.Copy(a3, 0, ret, a1.Length + a2.Length, a3.Length);
    return ret;
}

বিকল্পভাবে, আপনার যদি কেবল একটিমাত্র আইনিংরেবলের প্রয়োজন হয়, তবে সি # 2.0 ফলন অপারেটরটি ব্যবহার করে বিবেচনা করুন:

IEnumerable<byte> Combine(byte[] a1, byte[] a2, byte[] a3)
{
    foreach (byte b in a1)
        yield return b;
    foreach (byte b in a2)
        yield return b;
    foreach (byte b in a3)
        yield return b;
}

আমি বড় স্ট্রিমগুলিকে একীভূত করতে আপনার 2 য় বিকল্পের অনুরূপ কিছু করেছি, কবজির মতো কাজ করেছি। :)
গ্রেগ ডি

2
দ্বিতীয় বিকল্পটি দুর্দান্ত। +1 টি।
আর মার্টিনহো ফার্নান্দেস

10

আমি আসলে কনক্যাট ব্যবহার করে কিছু সমস্যা নিয়ে এসেছি ... (১০-কোটির মধ্যে অ্যারে দিয়ে, এটি আসলে ক্র্যাশ হয়েছিল)।

আমি নিম্নলিখিতগুলি সহজ, সহজ বলে মনে করেছি এবং আমার উপর ক্রাশ না করে যথেষ্ট কাজ করে এবং এটি যে কোনও সংখ্যক অ্যারে (কেবল তিন নয়) এর জন্য কাজ করে (এটি লিনকিউ ব্যবহার করে):

public static byte[] ConcatByteArrays(params byte[][]  arrays)
{
    return arrays.SelectMany(x => x).ToArray();
}

6

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

using (MemoryStream ms = new MemoryStream())
{
  ms.Write(BitConverter.GetBytes(22),0,4);
  ms.Write(BitConverter.GetBytes(44),0,4);
  ms.ToArray();
}

3
Qwe বিবৃত হিসেবে আমি 10,000,000 বার লুপ একটি পরীক্ষা করেছেন, এবং MemoryStream 290% এরও Buffer.BlockCopy ধীর বেরিয়ে আসেন
esac

কিছু ক্ষেত্রে আপনি স্বতন্ত্র অ্যারে দৈর্ঘ্যের কোনও পূর্বনির্দিষ্টতা ছাড়াই অগণিত অ্যারেগুলিতে পুনরাবৃত্তি করতে পারেন। এটি এই পরিস্থিতিতে ভাল কাজ করে। ব্লককপি একটি গন্তব্য অ্যারে পূর্ববর্তী হওয়া উপর নির্ভর করে
সেন্টিনেল

@ সেন্টিনেল যেমন বলেছে, এই উত্তরটি আমার পক্ষে নিখুঁত কারণ আমার কী আকারে লিখতে হবে সে সম্পর্কে আমার কোনও জ্ঞান নেই এবং আমাকে খুব পরিষ্কারভাবে জিনিসগুলি করতে দেয়। এটি নেট কোর 3 এর [পঠনযোগ্য] স্প্যান <বিট> এর সাথেও দুর্দান্ত খেলছে!
জল

আপনি যদি চূড়ান্ত আকারের মেমরির স্ট্রিমটি আকারের সাথে শুরু করেন তবে এটি পুনরায় তৈরি করা হবে না এবং এটি দ্রুত @ এসএসি হবে।
টোনো নাম

2
    public static bool MyConcat<T>(ref T[] base_arr, ref T[] add_arr)
    {
        try
        {
            int base_size = base_arr.Length;
            int size_T = System.Runtime.InteropServices.Marshal.SizeOf(base_arr[0]);
            Array.Resize(ref base_arr, base_size + add_arr.Length);
            Buffer.BlockCopy(add_arr, 0, base_arr, base_size * size_T, add_arr.Length * size_T);
        }
        catch (IndexOutOfRangeException ioor)
        {
            MessageBox.Show(ioor.Message);
            return false;
        }
        return true;
    }

দুর্ভাগ্যক্রমে এটি সমস্ত ধরণের সাথে কাজ করবে না। মার্শাল.সাইজঅফ () অনেক ধরণের জন্য একটি আকার ফিরিয়ে দিতে অক্ষম হবে (স্ট্রিংগুলির অ্যারে ব্যবহার করে এই পদ্ধতিটি ব্যবহার করার চেষ্টা করুন এবং আপনি একটি ব্যতিক্রম দেখতে পাবেন "টাইপ 'সিস্টেম St স্ট্রিং'কে একটি নিয়ন্ত্রণহীন কাঠামো হিসাবে মার্শাল করা যাবে না; কোনও অর্থবহ আকার বা অফসেটটি গণনা করা যায় "" আপনি টাইপ প্যারামিটারটি কেবলমাত্র রেফারেন্সের ধরণের (সংযোজন করে where T : struct) সীমাবদ্ধ করার চেষ্টা করতে পারেন , তবে - সিএলআরের অভ্যন্তরের বিশেষজ্ঞ না হয়ে - আপনি নির্দিষ্ট স্ট্রাকগুলিতেও ব্যতিক্রম পেতে পারেন কিনা তা আমি বলতে পারিনি I (উদাহরণস্বরূপ যদি সেগুলিতে রেফারেন্স প্রকারের ক্ষেত্রগুলি থাকে)
Daniel

2
    public static byte[] Concat(params byte[][] arrays) {
        using (var mem = new MemoryStream(arrays.Sum(a => a.Length))) {
            foreach (var array in arrays) {
                mem.Write(array, 0, array.Length);
            }
            return mem.ToArray();
        }
    }

আপনার উত্তরটি আরও ভাল হতে পারে যদি আপনি এই কোড নমুনাটি করেন তার একটি সামান্য ব্যাখ্যা পোস্ট করে had
এপ্রি

1
এটি একটি বৃহত বাইট অ্যারেতে বাইট অ্যারেগুলির একটি অ্যারে সংমিশ্রণ করে (এটির মতো): [1,2,3] + [৪,৫] + [,,7] ==> [১,২,৩,৪,৫ , 6,7]
পিটার আর্টল

1

অ্যারে একত্রিত করতে জেনেরিকগুলি ব্যবহার করতে পারেন। নিম্নলিখিত কোডটি সহজেই তিনটি অ্যারে প্রসারিত করা যায়। এই ধরণের অ্যারেগুলির জন্য আপনাকে কখনই কোড নকল করার প্রয়োজন হবে না। উপরের কিছু উত্তর আমার কাছে অতিরিক্ত জটিল বলে মনে হচ্ছে।

private static T[] CombineTwoArrays<T>(T[] a1, T[] a2)
    {
        T[] arrayCombined = new T[a1.Length + a2.Length];
        Array.Copy(a1, 0, arrayCombined, 0, a1.Length);
        Array.Copy(a2, 0, arrayCombined, a1.Length, a2.Length);
        return arrayCombined;
    }

0

এখানে @ জোন স্কিটের দেওয়া উত্তরের একটি সাধারণীকরণ দেওয়া আছে। এটি মূলত একই, কেবল এটি কোনও ধরণের অ্যারের জন্যই ব্যবহারযোগ্য, কেবল বাইটগুলি নয়:

public static T[] Combine<T>(T[] first, T[] second)
{
    T[] ret = new T[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

public static T[] Combine<T>(T[] first, T[] second, T[] third)
{
    T[] ret = new T[first.Length + second.Length + third.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
                     third.Length);
    return ret;
}

public static T[] Combine<T>(params T[][] arrays)
{
    T[] ret = new T[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (T[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

3
বিপদ! এই পদ্ধতিগুলি এক বাইটের চেয়ে দীর্ঘ উপাদানগুলির সাথে কোনও অ্যারের ধরণের সাথে সম্পত্তি নিয়ে কাজ করবে না (বাইট অ্যারে ব্যতীত অন্য সব কিছু)। বাফার.ব্লককপি () অ্যারে উপাদানগুলির সংখ্যা নয়, বাইটের পরিমাণ নিয়ে কাজ করে। বাইট অ্যারের সাহায্যে এটি সহজেই ব্যবহার করা যেতে পারে তার কারণ হ'ল অ্যারের প্রতিটি উপাদান একক বাইট, তাই অ্যারের দৈহিক দৈর্ঘ্য উপাদানগুলির সংখ্যার সমান হয়। জনের বাইট [] পদ্ধতিগুলিকে জেনেরিক পদ্ধতিতে রূপান্তর করতে আপনাকে একক অ্যারে উপাদানের বাইট-দৈর্ঘ্য দ্বারা সমস্ত অফসেট এবং দৈর্ঘ্য একাধিক করতে হবে - অন্যথায় আপনি সমস্ত ডেটা অনুলিপি করবেন না।
ড্যানিয়েল স্কট

2
সাধারণত এই কাজটি করার জন্য আপনি একটি একক উপাদান ব্যবহার করে একটি আকারের আকারটি গণনা করতে sizeof(...)এবং আপনার অনুলিপি করতে চান এমন উপাদানগুলির সংখ্যা দ্বারা গুণিত করতে চান, তবে আকারটি জেনেরিক টাইপের সাথে ব্যবহার করা যায় না। কিছু ধরণের জন্য - এটি ব্যবহার করা সম্ভব Marshal.SizeOf(typeof(T)), তবে আপনি নির্দিষ্ট ধরণের (যেমন স্ট্রিং) দিয়ে রানটাইম ত্রুটি পাবেন। সিএলআর প্রকারের অভ্যন্তরীণ কাজের আরও বিশদ জ্ঞান সহকারে কেউ এখানে সম্ভাব্য সমস্ত ফাঁদ চিহ্নিত করতে সক্ষম হবেন। বলার অপেক্ষা রাখে না যে জেনেরিক অ্যারে কনটেনটেশন পদ্ধতি [ব্লককপি ব্যবহার করে] লেখা তুচ্ছ নয়।
ড্যানিয়েল স্কট

2
এবং পরিশেষে - আপনি ঠিক এর পরিবর্তে অ্যারে.কপি ব্যবহার করে উপরে (কিছুটা কম পারফরম্যান্স সহ) প্রদর্শিত প্রায় একইভাবে একটি জেনেরিক অ্যারে কনটেনটেশন পদ্ধতি লিখতে পারেন। অ্যারে.কপি কলগুলির সাথে সমস্ত বাফার.ব্লককপি কলগুলি কেবল প্রতিস্থাপন করুন।
ড্যানিয়েল স্কট

0
    /// <summary>
    /// Combine two Arrays with offset and count
    /// </summary>
    /// <param name="src1"></param>
    /// <param name="offset1"></param>
    /// <param name="count1"></param>
    /// <param name="src2"></param>
    /// <param name="offset2"></param>
    /// <param name="count2"></param>
    /// <returns></returns>
    public static T[] Combine<T>(this T[] src1, int offset1, int count1, T[] src2, int offset2, int count2) 
        => Enumerable.Range(0, count1 + count2).Select(a => (a < count1) ? src1[offset1 + a] : src2[offset2 + a - count1]).ToArray();

অবদানের জন্য আপনাকে ধন্যবাদ। যেহেতু এক দশকেরও বেশি আগে থেকেই এর জন্য ইতিমধ্যে বেশ কয়েকটি উচ্চ রেটযুক্ত উত্তর রয়েছে, তাই আপনার পদ্ধতির কী আলাদা করে তার ব্যাখ্যা দেওয়া কার্যকর হবে। কেন কেউ উত্তর ব্যবহারের পরিবর্তে এটি ব্যবহার করা উচিত?
জেরেমি কেনে

আমি বর্ধিত পদ্ধতিগুলি ব্যবহার করতে পছন্দ করি কারণ বুঝতে স্পষ্ট কোড রয়েছে। এই কোডটি সূচনা সূচনা এবং গণনা এবং কনক্যাট সহ দুটি অ্যারে নির্বাচন করে। এছাড়াও এই পদ্ধতি প্রসারিত। সুতরাং, এটি সমস্ত সময়ের জন্য প্রস্তুত সমস্ত অ্যারে জন্য
মেহমেট ÜNLÜ

এটা আমার ভাল বোঝায়! আপনি কি এই তথ্য অন্তর্ভুক্ত আপনার প্রশ্ন সম্পাদনা করতে আপত্তি? আমি মনে করি ভবিষ্যতের পাঠকদের পক্ষে এগুলি সামনে রাখা মূল্যবান হবে, যাতে তারা আপনার উত্তরগুলি বিদ্যমান উত্তরগুলি থেকে দ্রুত আলাদা করতে পারে। ধন্যবাদ!
জেরেমি কেনে 21

-1

আপনাকে কেবলমাত্র বাইট অ্যারেগুলির তালিকা পাস করতে হবে এবং এই ফাংশনটি আপনাকে বাইটের অ্যারে (মার্জড) ফিরিয়ে দেবে। এটি আমার মনে হয় সবচেয়ে ভাল সমাধান :)।

public static byte[] CombineMultipleByteArrays(List<byte[]> lstByteArray)
        {
            using (var ms = new MemoryStream())
            {
                using (var doc = new iTextSharp.text.Document())
                {
                    using (var copy = new PdfSmartCopy(doc, ms))
                    {
                        doc.Open();
                        foreach (var p in lstByteArray)
                        {
                            using (var reader = new PdfReader(p))
                            {
                                copy.AddDocument(reader);
                            }
                        }

                        doc.Close();
                    }
                }
                return ms.ToArray();
            }
        }

-5

কনক্যাট হ'ল সঠিক উত্তর, তবে কোনও কারণে একটি নিয়ন্ত্রিত জিনিস সর্বাধিক ভোট পাচ্ছে। আপনি যদি উত্তরটি পছন্দ করেন তবে সম্ভবত আপনি আরও সাধারণ সমাধানটি আরও বেশি পছন্দ করতে পারেন:

    IEnumerable<byte> Combine(params byte[][] arrays)
    {
        foreach (byte[] a in arrays)
            foreach (byte b in a)
                yield return b;
    }

যা আপনাকে এই জাতীয় জিনিসগুলি করতে দেয়:

    byte[] c = Combine(new byte[] { 0, 1, 2 }, new byte[] { 3, 4, 5 }).ToArray();

5
প্রশ্নটি বিশেষভাবে সবচেয়ে দক্ষ সমাধানের জন্য জিজ্ঞাসা করে । অনুমিতযোগ্য T
জন স্কিটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.