简体   繁体   English

C#中动态列表数的比较

[英]Comparison of dynamic number of lists in C#

I have a variable number of List-objects, of which I need to compare the values at the same indexes. 我有一个可变数量的List对象,我需要比较相同索引的值。 The number of entries in the list is given and does not vary. 列表中的条目数是给定的,并且不会改变。

For example: 4 Lists each 4 entries 例如:4列出每4个条目

So what I'd be looking for in this example, is 4 bools, one per index. 所以我在这个例子中寻找的是4个bool,每个索引一个。 Getting the indexes of unmatching entries would be fine, too. 获取不匹配条目的索引也没关系。

Pseudo: 伪:

bool isFirstEqual = (list1[i] == list2[i] == list3[i] == list4[i]);

But I need to do this in a fashion that's applicable for a variable number of lists. 但我需要以适用于可变数量列表的方式执行此操作。 I could have 6 Lists, but also 2. 我可以有6个列表,但也有2个。

I was thinking of doing something with LINQs .Except() but am not sure how to use it with a variable number of lists. 我想用LINQs .Except .Except()做一些事情,但不知道如何使用可变数量的列表。

I am struggling to find the elegant solution that I'm sure is out there. 我很难找到我确信在那里的优雅解决方案。 Any help on this is appreciated. 对此有任何帮助表示赞赏。

If i understand what you mean, something like this might work 如果我理解你的意思,这样的事情可能有用

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

Usage 用法

var isSecondelemEqual = IsEqual(1, list1, list2, list3,...)

Update 更新

Basically takes a variable list of lists, and assumes you want to check the index of each list against each other. 基本上采用变量列表列表,并假设您要检查每个列表的索引。

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

Given for example: 举个例子:

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

So a List<> of List<int> 所以List<>List<int>

the totally unreadable LINQ expression that will return a List<bool> is something like: 返回List<bool>的完全不可读的LINQ表达式如下所示:

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();

Here I want to show you that if your first solution to any problem is LINQ, then perhaps now you will have two problems. 在这里,我想向您展示,如果您对问题的第一个解决方案是LINQ,那么现在您可能会遇到两个问题。

Now... What does this linq does? 现在......这个linq做了什么? We have 4 List<int> , each one with 3 elements... So 3 rows of 4 columns. 我们有4个List<int> ,每个有3个元素......所以3行4列。 We want to calculate the result "by row", so the first thing is discover the number of rows, that is listOfLists[0].Count (we put a pre-check for the case that we have 0 rows). 我们想要“按行”计算结果,所以第一件事是发现行数,即listOfLists[0].Count (我们对我们有0行的情况进行预检)。 Now we generate an index (like a for ), using Enumerable.Range(0, numberofrows) , like for (int i = 0; i < numberofrows; i++) . 现在我们使用Enumerable.Range(0, numberofrows)生成一个索引(比如for ),就像for (int i = 0; i < numberofrows; i++) For each row we see if there are 0 or 1 columns ( listOfLists.Count <= 1 ), then the result is true , otherwise we compare all the other columns y[x] with the first column listOfLists[0][x] . 对于每一行,我们看到是否有0或1列( listOfLists.Count <= 1 ),则结果为true ,否则我们将所有其他列y[x]与第一列listOfLists[0][x]

With a dual for cycle it becomes clearer probably: 有了双重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);
    }
}

Note that both programs can be simplified: new int[0].All(x => something) == true , so .All() on empty IEnumerable<> is true . 请注意,两个程序都可以简化: new int[0].All(x => something) == true ,因此空IEnumerable<>上的.All()true You can remove listOfLists.Count <= 1 ? true : 你可以删除listOfLists.Count <= 1 ? true : listOfLists.Count <= 1 ? true : and if (...) { ... } else up to the else keyword, keeping only the code inside the else : listOfLists.Count <= 1 ? true :if (...) { ... } elseelse关键字,只保留里面的代码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);

}

Here you go 干得好

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM