在C#中使用一个ForEach语句迭代两个List或Arrays

这只是一般的知识:

如果我有两个,让我们说, 列表 ,我想迭代两个相同的foreach循环,我们可以做到这一点?

编辑

为了澄清,我想这样做:

List<String> listA = new List<string> { "string", "string" }; List<String> listB = new List<string> { "string", "string" }; for(int i = 0; i < listA.Count; i++) listB[i] = listA[i]; 

但是用foreach =)

这被称为Zip操作,将在.NET 4中受支持。

这样,你就可以写下如下的东西:

 var numbers = new [] { 1, 2, 3, 4 }; var words = new [] { "one", "two", "three", "four" }; var numbersAndWords = numbers.Zip(words, (n, w) => new { Number = n, Word = w }); foreach(var nw in numbersAndWords) { Console.WriteLine(nw.Number + nw.Word); } 

作为具有命名字段的匿名types的替代方法,您还可以使用Tuple及其静态Tuple.Create助手来保存大括号:

 foreach (var nw in numbers.Zip(words, Tuple.Create)) { Console.WriteLine(nw.Item1 + nw.Item2); } 

如果你不想等.NET 4.0,你可以实现你自己的Zip方法。 下面的工作与.NET 2.0。 您可以根据您想要处理两种枚举(或列表)具有不同长度的情况来调整实现:这种方法会持续到较长枚举的末尾,从较短的枚举中返回缺less项的缺省值。

  static IEnumerable<KeyValuePair<T, U>> Zip<T, U>(IEnumerable<T> first, IEnumerable<U> second) { IEnumerator<T> firstEnumerator = first.GetEnumerator(); IEnumerator<U> secondEnumerator = second.GetEnumerator(); while (firstEnumerator.MoveNext()) { if (secondEnumerator.MoveNext()) { yield return new KeyValuePair<T, U>(firstEnumerator.Current, secondEnumerator.Current); } else { yield return new KeyValuePair<T, U>(firstEnumerator.Current, default(U)); } } while (secondEnumerator.MoveNext()) { yield return new KeyValuePair<T, U>(default(T), secondEnumerator.Current); } } static void Test() { IList<string> names = new string[] { "one", "two", "three" }; IList<int> ids = new int[] { 1, 2, 3, 4 }; foreach (KeyValuePair<string, int> keyValuePair in ParallelEnumerate(names, ids)) { Console.WriteLine(keyValuePair.Key ?? "<null>" + " - " + keyValuePair.Value.ToString()); } } 

你可以使用联合或Concat,前者删除重复,后者不

 foreach (var item in List1.Union(List1)) { //TODO: Real code goes here } foreach (var item in List1.Concat(List1)) { //TODO: Real code goes here } 

这是一个自定义IEnumerable <>扩展方法,可以用来同时循环两个列表。

 using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication1 { public static class LinqCombinedSort { public static void Test() { var a = new[] {'a', 'b', 'c', 'd', 'e', 'f'}; var b = new[] {3, 2, 1, 6, 5, 4}; var sorted = from ab in a.Combine(b) orderby ab.Second select ab.First; foreach(char c in sorted) { Console.WriteLine(c); } } public static IEnumerable<Pair<TFirst, TSecond>> Combine<TFirst, TSecond>(this IEnumerable<TFirst> s1, IEnumerable<TSecond> s2) { using (var e1 = s1.GetEnumerator()) using (var e2 = s2.GetEnumerator()) { while (e1.MoveNext() && e2.MoveNext()) { yield return new Pair<TFirst, TSecond>(e1.Current, e2.Current); } } } } public class Pair<TFirst, TSecond> { private readonly TFirst _first; private readonly TSecond _second; private int _hashCode; public Pair(TFirst first, TSecond second) { _first = first; _second = second; } public TFirst First { get { return _first; } } public TSecond Second { get { return _second; } } public override int GetHashCode() { if (_hashCode == 0) { _hashCode = (ReferenceEquals(_first, null) ? 213 : _first.GetHashCode())*37 + (ReferenceEquals(_second, null) ? 213 : _second.GetHashCode()); } return _hashCode; } public override bool Equals(object obj) { var other = obj as Pair<TFirst, TSecond>; if (other == null) { return false; } return Equals(_first, other._first) && Equals(_second, other._second); } } } 

如果列表具有相同的长度,则也可以简单地使用本地整数variables:

 List<classA> listA = fillListA(); List<classB> listB = fillListB(); var i = 0; foreach(var itemA in listA) { Console.WriteLine(itemA + listB[i++]); } 

我明白/希望名单有相同的长度:不,你唯一的赌注是循环的旧标准。

不,你将不得不使用for循环。

 for (int i = 0; i < lst1.Count; i++) { //lst1[i]... //lst2[i]... } 

你不能这样做

 foreach (var objCurrent1 int lst1, var objCurrent2 in lst2) { //... } 

如果你想要一个相应的元素,你可以做

 Enumerable.Range(0, List1.Count).All(x => List1[x] == List2[x]); 

如果每个项目都等于第二个列表中的相应项目,则返回true

如果这几乎不是你想要的,如果你详细阐述的话,这将有所帮助。

这种方法可以用于列表实现,可以作为扩展方法来实现。

 public void TestMethod() { var first = new List<int> {1, 2, 3, 4, 5}; var second = new List<string> {"One", "Two", "Three", "Four", "Five"}; foreach(var value in this.Zip(first, second, (x, y) => new {Number = x, Text = y})) { Console.WriteLine("{0} - {1}",value.Number, value.Text); } } public IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(List<TFirst> first, List<TSecond> second, Func<TFirst, TSecond, TResult> selector) { if (first.Count != second.Count) throw new Exception(); for(var i = 0; i < first.Count; i++) { yield return selector.Invoke(first[i], second[i]); } } 

从C#7开始,你可以使用元组…

 int[] nums = { 1, 2, 3, 4 }; string[] words = { "one", "two", "three", "four" }; foreach (var tuple in nums.Zip(words, (x, y) => (x, y))) { Console.WriteLine($"{tuple.Item1}: {tuple.Item2}"); } // or... foreach (var tuple in nums.Zip(words, (x, y) => (Num: x, Word: y))) { Console.WriteLine($"{tuple.Num}: {tuple.Word}"); }