C#中列表的动态数量比较
Comparison of dynamic number of lists in C#
我有可变数量的列表对象,我需要比较相同索引处的值。列表中的条目数是给定的,不会变化。
例如:
4 列表
每 4 个条目
所以我在这个例子中要寻找的是 4 个布尔值,每个索引一个。
获取不匹配条目的索引也可以。
伪:
bool isFirstEqual = (list1[i] == list2[i] == list3[i] == list4[i]);
但我需要以适用于可变数量列表的方式执行此操作。我可以有 6 个列表,但也有 2 个。
我正在考虑用 LINQ 做点什么 .Except()
但我不确定如何将它用于可变数量的列表。
我正在努力寻找我确定存在的优雅解决方案。
感谢您对此提供任何帮助。
bool AreIndexesEqual(int index, List<List<int>> lists)
{
int match = lists[0][index];
foreach(List<int> list in lists.Skip(1))
{
if (list[index] != match)
{
return false;
}
}
return true;
}
如果我明白你的意思,这样的方法可能有用
public static bool IsEqual<T>(int index, params List<T>[] ary)
{
for (var i = 1; i < ary.Length; i++)
if (!EqualityComparer<T>.Default.Equals(ary[0][index], ary[i][index]))
return false;
return true;
}
用法
var isSecondelemEqual = IsEqual(1, list1, list2, list3,...)
更新
基本上采用列表的可变列表,并假设您要相互检查每个列表的索引。
给出的例子:
List<List<int>> listOfLists = new List<List<int>>
{
new List<int> { 1, 100, 2},
new List<int> { 2, 100, 3},
new List<int> { 3, 100, 4},
new List<int> { 4, 100, 5},
};
所以 List<>
的 List<int>
完全不可读的 LINQ 表达式将 return 变成 List<bool>
类似于:
List<bool> result = Enumerable.Range(0, listOfLists.Count != 0 ? listOfLists[0].Count : 0)
.Select(x => listOfLists.Count <= 1 ?
true :
listOfLists.Skip(1).All(y => y[x] == listOfLists[0][x])
).ToList();
在这里我想告诉你,如果你对任何问题的第一个解决方案是 LINQ,那么现在你可能会遇到两个问题。
现在...这个 linq 有什么作用?我们有 4 个 List<int>
,每个有 3 个元素...所以 3 行 4 列。我们要计算结果 "by row",所以首先要找出行数,即 listOfLists[0].Count
(我们对有 0 行的情况进行了预检查)。现在我们生成一个索引(如 for
),使用 Enumerable.Range(0, numberofrows)
,如 for (int i = 0; i < numberofrows; i++)
。对于每一行,我们查看是否有 0 列或 1 列 (listOfLists.Count <= 1
),则结果为 true
,否则我们将所有其他列 y[x]
与第一列 listOfLists[0][x]
.
使用双 for
循环可能会变得更清晰:
var result2 = new List<bool>(listOfLists.Count != 0 ? listOfLists[0].Count : 0);
// Note the use of .Capacity here. It is listOfLists.Count != 0 ? listOfLists[0].Count : 0
for (int col = 0; col < result2.Capacity; col++)
{
if (listOfLists.Count <= 1)
{
result2.Add(true);
}
else
{
bool equal = true;
for (int row = 1; row < listOfLists.Count; row++)
{
if (listOfLists[row][col] != listOfLists[0][col])
{
equal = false;
break;
}
}
result2.Add(equal);
}
}
请注意,两个程序都可以简化:new int[0].All(x => something) == true
,因此 .All()
在空 IEnumerable<>
上是 true
。您可以删除 listOfLists.Count <= 1 ? true :
和 if (...) { ... } else
直到 else
关键字,只保留 else
:
中的代码
var result2 = new List<bool>(listOfLists.Count != 0 ? listOfLists[0].Count : 0);
// Note the use of .Capacity here. It is listOfLists.Count != 0 ? listOfLists[0].Count : 0
for (int col = 0; col < result2.Capacity; col++)
{
bool equal = true;
for (int row = 1; row < listOfLists.Count; row++)
{
if (listOfLists[row][col] != listOfLists[0][col])
{
equal = false;
break;
}
}
result2.Add(equal);
}
给你
IEnumerable<bool> CompareAll<T>(IEnumerable<IEnumerable<T>> source)
{
var lists = source.ToList();
var firstList = lists[0];
var otherLists = lists.Skip(1).ToList();
foreach(var t1 in firstList)
{
yield return otherlists.All(tn => tn.Equals(t1));
}
}
我有可变数量的列表对象,我需要比较相同索引处的值。列表中的条目数是给定的,不会变化。
例如: 4 列表 每 4 个条目
所以我在这个例子中要寻找的是 4 个布尔值,每个索引一个。 获取不匹配条目的索引也可以。
伪:
bool isFirstEqual = (list1[i] == list2[i] == list3[i] == list4[i]);
但我需要以适用于可变数量列表的方式执行此操作。我可以有 6 个列表,但也有 2 个。
我正在考虑用 LINQ 做点什么 .Except()
但我不确定如何将它用于可变数量的列表。
我正在努力寻找我确定存在的优雅解决方案。 感谢您对此提供任何帮助。
bool AreIndexesEqual(int index, List<List<int>> lists)
{
int match = lists[0][index];
foreach(List<int> list in lists.Skip(1))
{
if (list[index] != match)
{
return false;
}
}
return true;
}
如果我明白你的意思,这样的方法可能有用
public static bool IsEqual<T>(int index, params List<T>[] ary)
{
for (var i = 1; i < ary.Length; i++)
if (!EqualityComparer<T>.Default.Equals(ary[0][index], ary[i][index]))
return false;
return true;
}
用法
var isSecondelemEqual = IsEqual(1, list1, list2, list3,...)
更新
基本上采用列表的可变列表,并假设您要相互检查每个列表的索引。
给出的例子:
List<List<int>> listOfLists = new List<List<int>>
{
new List<int> { 1, 100, 2},
new List<int> { 2, 100, 3},
new List<int> { 3, 100, 4},
new List<int> { 4, 100, 5},
};
所以 List<>
的 List<int>
完全不可读的 LINQ 表达式将 return 变成 List<bool>
类似于:
List<bool> result = Enumerable.Range(0, listOfLists.Count != 0 ? listOfLists[0].Count : 0)
.Select(x => listOfLists.Count <= 1 ?
true :
listOfLists.Skip(1).All(y => y[x] == listOfLists[0][x])
).ToList();
在这里我想告诉你,如果你对任何问题的第一个解决方案是 LINQ,那么现在你可能会遇到两个问题。
现在...这个 linq 有什么作用?我们有 4 个 List<int>
,每个有 3 个元素...所以 3 行 4 列。我们要计算结果 "by row",所以首先要找出行数,即 listOfLists[0].Count
(我们对有 0 行的情况进行了预检查)。现在我们生成一个索引(如 for
),使用 Enumerable.Range(0, numberofrows)
,如 for (int i = 0; i < numberofrows; i++)
。对于每一行,我们查看是否有 0 列或 1 列 (listOfLists.Count <= 1
),则结果为 true
,否则我们将所有其他列 y[x]
与第一列 listOfLists[0][x]
.
使用双 for
循环可能会变得更清晰:
var result2 = new List<bool>(listOfLists.Count != 0 ? listOfLists[0].Count : 0);
// Note the use of .Capacity here. It is listOfLists.Count != 0 ? listOfLists[0].Count : 0
for (int col = 0; col < result2.Capacity; col++)
{
if (listOfLists.Count <= 1)
{
result2.Add(true);
}
else
{
bool equal = true;
for (int row = 1; row < listOfLists.Count; row++)
{
if (listOfLists[row][col] != listOfLists[0][col])
{
equal = false;
break;
}
}
result2.Add(equal);
}
}
请注意,两个程序都可以简化:new int[0].All(x => something) == true
,因此 .All()
在空 IEnumerable<>
上是 true
。您可以删除 listOfLists.Count <= 1 ? true :
和 if (...) { ... } else
直到 else
关键字,只保留 else
:
var result2 = new List<bool>(listOfLists.Count != 0 ? listOfLists[0].Count : 0);
// Note the use of .Capacity here. It is listOfLists.Count != 0 ? listOfLists[0].Count : 0
for (int col = 0; col < result2.Capacity; col++)
{
bool equal = true;
for (int row = 1; row < listOfLists.Count; row++)
{
if (listOfLists[row][col] != listOfLists[0][col])
{
equal = false;
break;
}
}
result2.Add(equal);
}
给你
IEnumerable<bool> CompareAll<T>(IEnumerable<IEnumerable<T>> source)
{
var lists = source.ToList();
var firstList = lists[0];
var otherLists = lists.Skip(1).ToList();
foreach(var t1 in firstList)
{
yield return otherlists.All(tn => tn.Equals(t1));
}
}