【问题标题】:Trying to compare two lists c# - Should work?试图比较两个列表 c# - 应该工作吗?
【发布时间】:2015-09-09 07:46:38
【问题描述】:

我有一个看起来像这样的方法:

GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)

首先,该方法创建一个新的List<string>,其中包含ImportData<string, bool> 中具有true 值的所有项目,并且可以在string[] ItemsToCompare 中找到

其次,我想将新的List<string> 与来自AllDrawings<string, List<string>> 的列表进行比较。该方法最终应该返回一个字符串,其中包含两个列表匹配的AllDrawings<string>, List<String>> 中的键。

我现在花了很多时间试图自己解决这个问题,并尝试了我在 Stackoverflow 上找到的类似问题的所有答案,但没有运气。

下面是我的方法的完整代码。如上所述,我尝试了很多不同的方法来比较列表,但下面的方法是最新的尝试。

  public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
    {
        string FinalDrawing = "";
        try
        {
            List<string> AllCorrect = new List<string>();
            foreach (var item in ImportData)
            {
                if (item.Value == true && ItemsToCompare.Contains(item.Key))
                    AllCorrect.Add(item.Key);
            }

            AllCorrect.Sort();

            foreach (var DrawItem in AllDrawings)
            {

                DrawItem.Value.Sort();
                var match = AllCorrect.SequenceEqual(DrawItem.Value);

                if (match == true)
                {
                    FinalDrawing = DrawItem.Key;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return FinalDrawing;
    }

我的问题是var match = AllCorrect.SequenceEqual(DrawItem.Value); 的返回值是false,因此永远不会设置FinalDrawing

非常感谢所有答案。 提前致谢!

【问题讨论】:

  • "该方法应该创建一个新的 List" 但您的示例方法返回 string - 它是什么?
  • @Jamiec 抱歉,这具有误导性。现在已经编辑了。返回类型并不那么重要,因为我在比较列表方面需要帮助,但您绝对正确,我的问题应该是一致的。
  • 您的AllCorrect 看起来不错。此外,对它进行排序并排序DrawItem.ValueSequenceEquals 看起来不错(假设没有小写/大写不匹配)(尽管我只是阅读它,没有尝试运行)。那么,您对所有这些实际上有什么问题?
  • 作为注释,如果一个方法做了两件事,那就是一对多。把它分开,然后从那里走。测试较小的人是否按照您期望的那样做。从那里继续。
  • Olivier - 你检查过这些字符串的内容了吗?也许他们有点不同。你能添加一些输入数据的样本吗?尤其是一两个imported 和一些你希望与他们匹配的alldrawings

标签: c# list compare sequence


【解决方案1】:

好的.. 我已经在 cmets 中说过了,但只是为了确保您不会因为不使用 linq 等而大喊大叫:

在您告诉我们的点上,您的程序似乎是正确的。

这是一个简单的测试。我提供了一些存根数据,涵盖了您似乎要检查的所有内容:

  • 只有 true 来自导入数据的东西
  • 仅比较 items 中列出的内容
  • 输入列表未排序

->http://rextester.com/HAE73942

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

public class Program
{
    // your original function, nothing changed
    public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
    {
        string FinalDrawing = "";
        try
        {
            List<string> AllCorrect = new List<string>();
            foreach (var item in ImportData)
            {
                if (item.Value == true && ItemsToCompare.Contains(item.Key))
                    AllCorrect.Add(item.Key);
            }

            AllCorrect.Sort();

            foreach (var DrawItem in AllDrawings)
            {

                DrawItem.Value.Sort();
                var match = AllCorrect.SequenceEqual(DrawItem.Value);

                if (match == true)
                {
                    FinalDrawing = DrawItem.Key;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return FinalDrawing;
    }

        public static void Main(string[] args)
        {
            var allDrawings = new Dictionary<string, List<string>>();
            allDrawings.Add("aaa", new List<string>{ "a03", "a01", "a02" }); // originally unsorted
            allDrawings.Add("bbb", new List<string>{ "b03", "b01", "b02" }); // originally unsorted
            allDrawings.Add("ccc", new List<string>{ "c03", "c01", "c02" }); // originally unsorted

            var import = new Dictionary<string, bool>();
            import.Add("b01", false); // falsey
            import.Add("a05", true); // not in comparison
            import.Add("a03", true);
            import.Add("c01", false); // falsey
            import.Add("a02", true);
            import.Add("a04", true); // not in comparison
            import.Add("a01", true);

            var toCompare = new string[9];
            toCompare[0]="a01"; toCompare[1]="a02"; toCompare[2]="a03";
            toCompare[3]="b01"; toCompare[4]="b02"; toCompare[5]="b03";
            toCompare[6]="c01"; toCompare[7]="c02"; toCompare[8]="c03";

            var result = GetDrawing(allDrawings, import, toCompare);

            Console.WriteLine("Result: " + result);
        }
}

它可以正常工作并按应有的方式打印aaa

这意味着您必须忽略输入数据中的某些内容。也许有些字符串是大写/小写的?也许有些字符串内部有空格,而其他字符串没有?

【讨论】:

  • 你是对的。我回去检查了我的整个代码,我发现我有另一种方法可以用来拆分干扰这个字符串的字符串。这就是它单独工作的原因,但是我在我的程序中尝试过它,结果是错误的。感谢您确认我的代码确实有效,这给了我浏览所有其他代码的动力。
  • 很遗憾,我不能接受两个答案。但感谢所有帮助。
【解决方案2】:

这段代码:

        List<string> AllCorrect = new List<string>();

        foreach (var item in ImportData)
        {
            if (item.Value == true && ItemsToCompare.Contains(item.Key))
                AllCorrect.Add(item.Key);
        }

        AllCorrect.Sort();

可以简化为:

     List<string> AllCorect = ImportData.Where(vp => 
       ItemsToCompare.Contains(vp.Key) && vp.Value).Select(vp => vp.Key).OrderBy(vp => vp).ToList();

要解决第二个问题,您可以这样做:

return AllDrawings.First(l => l.Value.OrderBy(l2 => l2).SequenceEqual(AllCorect)).Key;

附: 如果First() 总是抛出异常,则表明问题在于该列表如何填充值,这是一个不同的问题。

例子:

    public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
    {
        List<string> AllCorect = ImportData.Where(vp => 
           ItemsToCompare.Contains(vp.Key) && vp.Value).Select(vp => vp.Key).OrderBy(vp => vp).ToList();

        return AllDrawings.First(l => l.Value.OrderBy(l2 => l2).SequenceEqual(AllCorect)).Key;
    }


    static void Main(string[] args)
    {
        List<string> list1 = new List<string>() { "one", "two", "three" };
        List<string> list2 = new List<string>() { "five", "six", "seven" };

        Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>()
        {
            {"first", list1}, {"second", list2}
        };

        string[] itemsToCompare = { "one", "two", "three" };

        var dict2 = new Dictionary<string, bool>()
        {
            {"one", true},
            {"two", true},
            {"three", true}
        };

        var result = GetDrawing(dict, dict2, itemsToCompare);

        Console.WriteLine(result);
    }

输出:first

【讨论】:

  • 我喜欢 linq,我的反应也是这样,直到我读到那个代码,直到我读到问题是关于:(...) the return value from var match = AllCorrect.SequenceEqual(DrawItem.Value); is false and therefore the FinalDrawing is never set.。如果 SeqEqls 不匹配,则不匹配。对 OP 问题的回答应该解决这个问题,而不仅仅是用 linq 压缩代码。
  • 是的。这意味着 OP 应该已经有了答案 - 他们的序列 not 相等!
  • @Jamiec - 但他们是平等的。即使我使用 {"one", "two"} 之类的数据添加自己的示例,它也会返回 false。我目前正在为您构建一些示例,不幸的是,我无法发布我使用的当前数据,因为它是由我的公司分类的。
  • @Oliver - 如果它们相等,它将返回 true - 像这样:rextester.com/VNPSY41217
  • @Oliver 我已经用示例更新了我的答案。它工作得很好。
【解决方案3】:

如果字符串也确实匹配,那么您的代码将是正确的。我建议您检查您的字符串序列 - 创建一个可读的字符串并添加适当的断点。如果这里缺少的话,也尝试不区分大小写

    AllCorrect.Sort(StringComparer.InvariantCultureIgnoreCase);
    var AllCorrectInfo = string.Join(", ", AllCorrect.ToArray());
    foreach (var DrawItem in AllDrawings)
    {

        DrawItem.Value.Sort();
        var DrawItemInfo = string.Join(", ", DrawItem.Value.ToArray());

        var match = AllCorrect.SequenceEqual(DrawItem.Value, StringComparer.InvariantCultureIgnoreCase);

        if (match == true)
        {
            FinalDrawing = DrawItem.Key;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    相关资源
    最近更新 更多