दो सूचियों को एक साथ जोड़ना


333

यदि मेरे पास टाइप स्ट्रिंग (या किसी अन्य प्रकार) की दो सूचियाँ हैं, तो दो सूचियों में शामिल होने का एक त्वरित तरीका क्या है?

आदेश वही रहना चाहिए। डुप्लिकेट को हटा दिया जाना चाहिए (हालांकि दोनों लिंक में प्रत्येक आइटम अद्वितीय हैं)। मुझे इस पर बहुत कुछ नहीं मिला जब googling और डिलीवरी की गति के लिए किसी भी .NET इंटरफेस को लागू नहीं करना चाहता था।


5
क्या आदेश मायने रखता है? क्या आप डुप्लिकेट को बनाए रखना चाहते हैं?
लार्सनल

जवाबों:


573

तुम कोशिश कर सकते हो:

List<string> a = new List<string>();
List<string> b = new List<string>();

a.AddRange(b);

MSDN पृष्ठ के लिए AddRange

यह सूचियों के क्रम को संरक्षित करता है, लेकिन यह किसी भी डुप्लिकेट को नहीं हटाता है जो Unionऐसा करेगा।

यह सूची में परिवर्तन करता है a। यदि आप मूल सूचियों को संरक्षित करना चाहते हैं तो आपको उपयोग करना चाहिए Concat(जैसा कि अन्य उत्तरों में बताया गया है):

var newList = a.Concat(b);

यह तब तक रिटर्न करता है IEnumerableजब तक कि aयह अशक्त न हो जाए।


27
कोई नहीं वास्तव में कब किस विधि का उपयोग करने के लिए चला गया। AddRange जगह में एक सूची को संपादित करता है, इसमें दूसरी सूची जोड़ देता है (जैसे कि आपने फोन किया है। जोड़ें (foo) बार का एक गुच्छा)। कॉनैट और यूनियन एक्सटेंशन के तरीके मूल सूची को नहीं बदलते हैं। वे आलसी रूप से एक नया IEnumerable का निर्माण करते हैं और आवश्यक होने तक मूल सूची के सदस्यों तक भी नहीं पहुंच पाएंगे। जैसा कि उल्लेख किया गया है, संघ डुप्लिकेट को हटा देता है जबकि अन्य नहीं करते हैं।
शॉनफुमो

4
क्या किसी को पता है कि इस पद्धति की जटिलता क्या है? (यह बहुत शर्म की बात है कि Microsoft अपने MSDN के हिस्से के रूप में इस महत्वपूर्ण जानकारी की आपूर्ति नहीं करता है)
याकूब

2
मैं आपको सलाह देता हूं कि वह विभिन्न दृष्टिकोणों की इस अच्छी तुलना की जांच करें। विभिन्न विकल्पों के कुछ प्रदर्शन विश्लेषण भी दिखाएं: मर्ज कलेक्शन
बोगेमैन

यह पूरी तरह से काम करता है। आधा मिलियन से अधिक वस्तुओं पर कंकट () का उपयोग कर रहा था, जिसमें कई मिनट लगे। इस दृष्टिकोण में 5 सेकंड से भी कम समय लगता है।
ग्रीनफ्रेट 95

111

कम से कम स्पेस ओवरहेड के साथ जिस तरह से कॉनैट एक्सटेंशन पद्धति का उपयोग करना है।

var combined = list1.Concat(list2);

यह एक उदाहरण बनाता है, IEnumerable<T>जो उस क्रम में list1 और list2 के तत्वों की गणना करेगा।


2
using System.Linq;
कोनैट

43

संघ विधि अपने जरूरतों को पूरा कर सकते हैं। आपने निर्दिष्ट नहीं किया है कि आदेश या डुप्लिकेट महत्वपूर्ण था या नहीं।

दो IEnumerables ले लो और एक संघ प्रदर्शन के रूप में यहाँ देखा:

int[] ints1 = { 5, 3, 9, 7, 5, 9, 3, 7 };
int[] ints2 = { 8, 3, 6, 4, 4, 9, 1, 0 };

IEnumerable<int> union = ints1.Union(ints2);

// yields { 5, 3, 9, 7, 8, 6, 4, 1, 0 } 

24

कुछ इस तरह:

firstList.AddRange (secondList);

या, आप 'Union' एक्सटेंशन मेथड का उपयोग कर सकते हैं जो System.Linq में परिभाषित है। 'संघ' के साथ, आप एक तुलना भी निर्दिष्ट कर सकते हैं, जिसका उपयोग यह निर्दिष्ट करने के लिए किया जा सकता है कि किसी आइटम को संघ होना चाहिए या नहीं।

ऐशे ही:

List<int> one = new List<int> { 1, 2, 3, 4, 5 };
List<int> second=new List<int> { 1, 2, 5, 6 };

var result = one.Union (second, new EqComparer ());

foreach( int x in result )
{
    Console.WriteLine (x);
}
Console.ReadLine ();

#region IEqualityComparer<int> Members
public class EqComparer : IEqualityComparer<int>
{
    public bool Equals( int x, int y )
    {
        return x == y;
    }

    public int GetHashCode( int obj )
    {
        return obj.GetHashCode ();
    }
}
#endregion

17
targetList = list1.Concat(list2).ToList();

यह ठीक काम कर रहा है मुझे ऐसा लगता है। जैसा कि पहले कहा गया था, कॉनैट एक नया अनुक्रम देता है और परिणाम को सूची में परिवर्तित करते समय, यह पूरी तरह से काम करता है। AddRange पद्धति का उपयोग करते समय कभी-कभी असफल रूपांतरण विफल हो सकते हैं।


13

यदि आपके द्वारा उपयोग की जा सकने वाली दोनों सूचियों में कुछ आइटम मौजूद हैं

var all = list1.Concat(list2).Concat(list3) ... Concat(listN).Distinct().ToList();

7

जब तक वे एक ही प्रकार के होते हैं, यह AddRange के साथ बहुत सरल है:

list2.AddRange(list1);

7
var bigList = new List<int> { 1, 2, 3 }
    .Concat(new List<int> { 4, 5, 6 })
    .ToList(); /// yields { 1, 2, 3, 4, 5, 6 }

मुझे भी यह पसंद है। बहुत आसान। धन्यवाद।
गुरदीप

मुझे यह पसंद है क्योंकि यह या तो सूची को म्यूट नहीं करता है।
ईव।


4
List<string> list1 = new List<string>();
list1.Add("dot");
list1.Add("net");

List<string> list2 = new List<string>();
list2.Add("pearls");
list2.Add("!");

var result = list1.Concat(list2);


2

एक तरह से, मैंने उल्लेख नहीं किया है कि यह थोड़ा अधिक मजबूत हो सकता है, खासकर यदि आप प्रत्येक तत्व को किसी तरह बदलना चाहते थे (जैसे आप .Trim()सभी तत्वों को चाहते थे ।

List<string> a = new List<string>();
List<string> b = new List<string>();
// ...
b.ForEach(x=>a.Add(x.Trim()));

1

इस लिंक को देखें

public class ProductA
{ 
public string Name { get; set; }
public int Code { get; set; }
}

public class ProductComparer : IEqualityComparer<ProductA>
{

public bool Equals(ProductA x, ProductA y)
{
    //Check whether the objects are the same object. 
    if (Object.ReferenceEquals(x, y)) return true;

    //Check whether the products' properties are equal. 
    return x != null && y != null && x.Code.Equals(y.Code) && x.Name.Equals(y.Name);
    }

public int GetHashCode(ProductA obj)
{
    //Get hash code for the Name field if it is not null. 
    int hashProductName = obj.Name == null ? 0 : obj.Name.GetHashCode();

    //Get hash code for the Code field. 
    int hashProductCode = obj.Code.GetHashCode();

    //Calculate the hash code for the product. 
    return hashProductName ^ hashProductCode;
}
}


    ProductA[] store1 = { new ProductA { Name = "apple", Code = 9 }, 
                   new ProductA { Name = "orange", Code = 4 } };

    ProductA[] store2 = { new ProductA { Name = "apple", Code = 9 }, 
                   new ProductA { Name = "lemon", Code = 12 } };

// दोनों सरणियों से उत्पाद प्राप्त करें // डुप्लिकेट को छोड़कर।

IEnumerable<ProductA> union =
  store1.Union(store2);

foreach (var product in union)
    Console.WriteLine(product.Name + " " + product.Code);

/*
    This code produces the following output:

    apple 9
    orange 4
    lemon 12
*/

1

मेरे द्वारा उपयोग किए जाने वाले दो विकल्प हैं:

list1.AddRange(list2);

या

list1.Concat(list2);

हालाँकि, मैंने देखा कि जब मैंने AddRangeएक पुनरावर्ती फ़ंक्शन के साथ विधि का उपयोग किया था , तो यह अपने आप में बहुत बार कॉल करता है कि मुझे एक SystemOutOfMemoryException मिली क्योंकि अधिकतम संख्या में आयाम पहुंच गए थे।

(संदेश Google अनुवादित)
सरणी आयाम समर्थित सीमा से अधिक है।

Concatउस मुद्दे को हल करने का उपयोग करना ।


0

मैं सिर्फ यह परीक्षण करना चाहता था कि Unionसंदर्भ प्रकार की वस्तुओं के अतिव्यापी संग्रह पर डिफ़ॉल्ट तुलना के साथ कैसे काम करता है।

मेरी वस्तु है:

class MyInt
{
    public int val;

    public override string ToString()
    {
        return val.ToString();
    }
}

मेरा परीक्षण कोड है:

MyInt[] myInts1 = new MyInt[10];
MyInt[] myInts2 = new MyInt[10];
int overlapFrom = 4;
Console.WriteLine("overlapFrom: {0}", overlapFrom);

Action<IEnumerable<MyInt>, string> printMyInts = (myInts, myIntsName) => Console.WriteLine("{2} ({0}): {1}", myInts.Count(), string.Join(" ", myInts), myIntsName);

for (int i = 0; i < myInts1.Length; i++)
    myInts1[i] = new MyInt { val = i };
printMyInts(myInts1, nameof(myInts1));

int j = 0;
for (; j + overlapFrom < myInts1.Length; j++)
    myInts2[j] = myInts1[j + overlapFrom];
for (; j < myInts2.Length; j++)
    myInts2[j] = new MyInt { val = j + overlapFrom };
printMyInts(myInts2, nameof(myInts2));

IEnumerable<MyInt> myUnion = myInts1.Union(myInts2);
printMyInts(myUnion, nameof(myUnion));

for (int i = 0; i < myInts2.Length; i++)
    myInts2[i].val += 10;
printMyInts(myInts2, nameof(myInts2));
printMyInts(myUnion, nameof(myUnion));

for (int i = 0; i < myInts1.Length; i++)
    myInts1[i].val = i;
printMyInts(myInts1, nameof(myInts1));
printMyInts(myUnion, nameof(myUnion));

आउटपुट है:

overlapFrom: 4
myInts1 (10): 0 1 2 3 4 5 6 7 8 9
myInts2 (10): 4 5 6 7 8 9 10 11 12 13
myUnion (14): 0 1 2 3 4 5 6 7 8 9 10 11 12 13
myInts2 (10): 14 15 16 17 18 19 20 21 22 23
myUnion (14): 0 1 2 3 14 15 16 17 18 19 20 21 22 23
myInts1 (10): 0 1 2 3 4 5 6 7 8 9
myUnion (14): 0 1 2 3 4 5 6 7 8 9 20 21 22 23

तो, सब कुछ ठीक काम करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.