मैं 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
"कुशल" से आपका क्या अभिप्राय है? कोड काफी छोटा है जैसा कि यह है, इसलिए मुझे लगता है कि आप सीपीयू / रैम के मामले में कुशल हैं?
टीटोनी

4
नहीं, परावर्तक के साथ एक त्वरित रूप से पता चलता है कि यह एक डबल-जब-पूर्ण बफर का उपयोग करता है
erikkallen

बस स्पष्ट होना चाहिए मुझे एक प्रकार का इंट [] होने के लिए z की आवश्यकता है।
hwiechers

4
मैं वास्तव में दक्षता के बारे में चिंतित नहीं हूं। (मैंने आसान या अधिक कुशल कहा।) मैंने यह जांचने के लिए सवाल पूछा कि अन्य लोग इस सामान्य कार्य को कैसे संभाल रहे थे।
hwiechers

जवाबों:


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

8
@manthrax -> अपने बचाव में, C # उन सूचियों का पक्ष लेता है जो सरणियों की तुलना में बहुत अधिक शक्तिशाली हैं। ऐसा लगता है कि सरणियों का उपयोग करने के लिए एकमात्र कार्यात्मक उद्देश्य इंटरोप कॉल (अप्रबंधित सी ++) के लिए है।
लेवी फुलर

@LeviFuller चर # का उपयोग करने वाला एक अन्य स्थान चर-संख्या paramsमापदंडों के साथ है।
क्रिस डब्ल्यूडब्ल्यू

1
@LeviFuller - यह अजीब है कि कई सिस्टम रूटीन सूची के बजाय सरणियाँ लौटाते हैं। उदाहरण System.IO.Directory.GetFiles()के लिए तार की एक सरणी देता है।
ओरियन एल्जेनिल

4
यह अजीब नहीं है। एक सरणी अपरिवर्तनीय है, एक सूची नहीं है। इसके अलावा एक सूची एक सरणी की तुलना में अधिक मेमोरी का उपयोग करती है, जब तक कि ट्रिमएक्सैस को नहीं कहा जाता है (जो टॉलिस्ट में नहीं होता है)
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
आप पहली पंक्ति सूची बनाना चाहते हैं <int> सूची = नई सूची <int> (x.Length + y.Length); जैसा कि आप AddRange
माइक टू

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% में हैं, हालांकि, तो कुछ प्रत्यक्ष मेमोस्कोपी / सरणी का काम आसान है।
मार्क Gravell

1
@nawfal, से Copyतेज कैसे है CopyTo? विस्तृत करने के लिए परवाह?
स्क्रेबेल

1
@skrebbel मेरा एक गलत टिप्पणी थी। मैंने कुछ परीक्षण वापस किए और मुझे कॉपी तेजी से मिली। लेकिन अब लगता है कि वे बस बराबर हैं। जो मुझे वापस मिल सकता है, वह यह हो सकता है कि समग्र रूप से मार्क का दृष्टिकोण अधिक कुशल है क्योंकि वह एक ही उदाहरण वापस कर रहा है जबकि जेड के दृष्टिकोण में वह एक नया सरणी बना रहा है। माफी :)
nawfal

1
@ शमी ऐसा नहीं होगा। इस विधि के अंदर x है, लेकिन एक स्थानीय चर है, जिसे आकार बदलने की विधि के लिए रेफरी के रूप में पास करने से एक नया सरणी बन जाएगा और इसे इंगित करने के लिए (स्थानीय चर) 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[][]लिए बदल दिया गया ।
मार्क

हाय दोस्तों, यह फंक्शन वैसा ही दिखता है जैसा मैं देख रहा था, लेकिन किसी भी विचार मैं इसे कैसे प्राप्त करूं? लिंक @ मर्क
जॉर्ज बी

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();आप
कॉनराट को

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 () कॉल को अंत तक ले जा सकते हैं। क्या कॉनैट को कॉल करने के बाद आपको एक सरणी होने की आवश्यकता है?

कॉनकैट कॉलिंग दोनों सरणियों पर एक पुनरावृत्ति बनाता है। यह एक नया सरणी नहीं बनाता है इसलिए आपने नए सरणी के लिए अधिक मेमोरी का उपयोग नहीं किया है। जब आप ToArray कहते हैं, तो आप वास्तव में एक नई सरणी बनाते हैं और नए सरणी के लिए मेमोरी लेते हैं।

इसलिए अगर आपको बस दोनों पर आसानी से पुनरावृत्ति करने की आवश्यकता है तो बस कॉनसैट को कॉल करें।


8

मुझे पता है कि ओपी केवल प्रदर्शन के बारे में हल्का उत्सुक था। उस बड़े सरणियों को एक अलग परिणाम मिल सकता है (देखें @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();
        }
    }

}

परिणाम था:

यहां छवि विवरण दर्ज करें

अपनी जीत जीतें।


विधियों का उपयोग करने वाले तरीकों के लिए निष्पक्षता में, मेथड्स ने संभवतः मेरे सिस्टम पर लगभग 10,000 टिक जोड़े।
अमलगमेट

1
मैंने रिलीज़ कोड 2013 में आपके कोड को रिलीज़ मोड में चलाया और पाया कि, यदि परीक्षण किया गया सरणी इतना छोटा नहीं है जितना आपका (जैसे 1000 तत्व), CopyToतो सबसे तेज़ और ~ 3x अधिक तेज़ होगा Roll your own
श्री री

@ Mr.Ree हाँ, मेरा सरणी वास्तव में छोटा था यह नहीं था। धन्यवाद। यदि ब्लॉक प्रति और भी बेहतर होता है देखने के लिए रुचि रखते हैं ...
मिलाना

7

Concatविधि से सावधान रहें । C # में एरियर कॉनट्रैटेनेशन पोस्ट बताता है कि:

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

बड़े सरणियों के लिए अक्षम होगा। इसका मतलब है कि Concatविधि केवल मध्य-आकार के सरणियों (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
यह सुनिश्चित नहीं है कि "यह" पहले परम से पहले क्या कर रहा है, लेकिन बाकी के लिए, यह एक उत्कृष्ट कार्य है। सामान्य, और मापदंडों की एक अनंत राशि के साथ।
Nyerguds

2
हाय Nyerguds। आपके प्रश्न का उत्तर देने के लिए, फ़ंक्शन को एक्सटेंशन विधि बनाने के लिए "इस" कीवर्ड का उपयोग किया जाता है। विस्तार के तरीकों के बारे में अधिक जानकारी के लिए इस 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 मी

CopyTo ने 1079ms लिया

ब्लॉककॉपी ने 603 मी

यदि मैं 0 से 99 तक परीक्षण सरणियों को दो अनुक्रमों में बदल देता हूं तो मुझे इसके समान परिणाम मिलते हैं,

कॉनैट ने 45945ms लिया

CopyTo ने 2230ms लिया

ब्लॉककॉपी ने 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

संयुक्त सरणी रखने के लिए RAM (और CPU) के संदर्भ में सबसे कुशल संरचना एक विशेष वर्ग होगी जो IEnumerable (या यदि आप ऐरे से भी प्राप्त करना चाहते हैं) को लागू करता है और मूल्यों को पढ़ने के लिए मूल सरणियों से आंतरिक रूप से जोड़ता है। 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];

@ नवाफ मुझे लगता है कि सरणी आकार पर निर्भर करेगा। इसने मेरे छोटे सरणी आकार का परीक्षण जीता।
मिलाना

2

मुझे LINQ या लैम्ब्डा एक्सप्रेशन का उपयोग करके एक सुंदर एक लाइन सॉल्यूशन मिला है , दोनों एक ही काम करते हैं (LINQ लैम्बडा में परिवर्तित हो जाता है जब प्रोग्राम कम्पाइल होता है)। समाधान किसी भी सरणी प्रकार और किसी भी संख्या में सरणियों के लिए काम करता है।

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's या @ deepee1 के समाधान थोड़े तेज़ हैं, लैम्ब्डा अभिव्यक्ति सबसे धीमी है। समय लिया सरणी तत्वों के प्रकार (ओं) पर निर्भर है, लेकिन जब तक लाखों कॉल नहीं होते हैं, तब तक विधियों के बीच कोई महत्वपूर्ण अंतर नहीं है।


1

आपको याद रखने की आवश्यकता है कि LINQ का उपयोग करते समय आप विलंबित निष्पादन का उपयोग कर रहे हैं। यहां वर्णित अन्य विधियां पूरी तरह से काम करती हैं, लेकिन उन्हें तुरंत निष्पादित किया जाता है। इसके अलावा कॉनकैट () फ़ंक्शन को संभवतः उन तरीकों से अनुकूलित किया जाता है जो आप स्वयं नहीं कर सकते (आंतरिक एपीआई के कॉल, ओएस कॉल आदि)। वैसे भी, जब तक आपको वास्तव में प्रयास करने और अनुकूलन करने की आवश्यकता नहीं होती है, आप वर्तमान में "सभी बुराई की जड़" के पथ पर हैं;)


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 के लिए [] आपने जो किया है वह मुझे अच्छा लग रहा है। समझने वाले का जवाब भी अच्छा होगा List<int>


2
कॉनसैट लिस्ट <int> के लिए भी काम करेगा। कॉनैट के बारे में यह बहुत अच्छा है, यह किसी भी 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 और न ही सूची का उपयोग नहीं करता है।

ध्यान दें कि समाधान संक्षिप्त है और जोड़ा गया सामान्यता ओवरटाइम के ऊपरी भाग को नहीं जोड़ता है।


मैं नए प्रश्नों को खोजने की कोशिश करूँगा या जिनके पास पहले से ही कई जवाब नहीं हैं - जिसमें आपके जैसे एक बहुत ज्यादा शामिल हैं।
एंड्रयू बार्बर

मैंने इस समाधान का प्रस्ताव किया क्योंकि मुझे लगता है कि यह संक्षेप में बताता है कि अन्य लोगों से क्या अच्छा है। इसे गढ़ा गया था।
14'14

-2

int [] x = नया int [] {१, २, ३}; int [] y = नया int [] {४, ५};

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


2
Unionयह एक बहुत अच्छा तरीका नहीं है क्योंकि यह अंतर्निहित कॉल करता है Distinctऔर सम्मिलित संग्रह से किसी डुप्लिकेट को निकालता है। Concatबहुत बेहतर है, लेकिन यह पहले से ही मूल प्रश्न में है।
नुरची

-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 Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.