将两个列表连接在一起

如果我有类型字符串(或任何其他类型)的两个列表,什么是连接两个列表的快速方法?

顺序应该保持不变。应该删除重复的内容(尽管两个链接中的每一项都是唯一的)。当我在谷歌上搜索的时候,我并没有找到太多关于这方面的信息,也不想为了加快交付速度而实现任何。net接口。

594974 次浏览

就像这样:

firstList.AddRange (secondList);
或者,您可以使用在System.Linq中定义的'Union'扩展方法。 使用'Union',你还可以指定一个比较器,它可以用来指定一个项是否应该合并

是这样的:

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

你可以试试:

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


a.AddRange(b);

MSDN page for AddRange

这保留了列表的顺序,但它没有像Union那样删除任何重复项。

这确实会改变列表a。如果你想保留原始列表,那么你应该使用Concat(正如在其他答案中指出的那样):

var newList = a.Concat(b);

只要a不为空,就返回IEnumerable

联盟方法可以满足你的需求。你没有说明订单还是副本是重要的。

取两个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 }

一种方法:List.AddRange()取决于类型?

AddRange方法

aList.AddRange( anotherList );

空间开销最小的方法是使用Concat扩展方法。

var combined = list1.Concat(list2);

它创建了IEnumerable<T>的实例,该实例将按顺序枚举list1和list2的元素。

只要它们是同一类型的,用AddRange就很简单:

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

如果两个列表中都有一些项目,你可以使用

var all = list1.Concat(list2).Concat(list3) ... Concat(listN).Distinct().ToList();
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);
targetList = list1.Concat(list2).ToList();

我想它运行得很好。如前所述,Concat返回一个新的序列,在将结果转换为List时,它完美地完成了工作。使用AddRange方法时,隐式转换有时可能会失败。

请看这个链接

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

//从两个数组中获取乘积 / /不含重复。< / p >

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
*/

我只是想测试在引用类型对象的重叠集合上,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

所以,一切正常。

我使用的两个选项是:

list1.AddRange(list2);

list1.Concat(list2);

然而,我注意到,当我使用带有递归函数的AddRange方法时,它经常调用自己,我得到了一个SystemOutOfMemoryException,因为达到了最大维度数。

(Message谷歌Translated)
. .日志含义

使用Concat解决了这个问题。

有一种方法,我还没有看到提到过,可以更健壮一点,特别是如果你想以某种方式改变每个元素(例如,你想.Trim()所有的元素。

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