C#中的Linq查询无法按预期工作

时间:2010-07-16 13:16:31

标签: c# asp.net-mvc linq

我在控制台应用中重现了我的问题。以下是代码。

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

namespace LinqSample
{
    class Program
    {
        static void Main(string[] args)
        {
            string query = "Maine, Maryland, Massachusetts, M";

            var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries);
            string lastQuery = queries[queries.Length - 1].Trim();

            if (queries.Length > 1)
            {
                var remQueries = queries.Take(queries.Length - 1).ToArray();

                string[] suggestions = new string[] {"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", 
            "Mississippi", "Missouri", "Montana"};

                System.Console.WriteLine("Before Except ");

                suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); });

                var unqiueSugs = from sug in suggestions
                                 where !remQueries.Any(q => q.Equals(sug, StringComparison.OrdinalIgnoreCase))
                                 select sug;

                if (unqiueSugs != null)
                {
                    suggestions = unqiueSugs.ToArray();
                }

                System.Console.WriteLine("\n After Except ");
                suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); });
            }
        }
    }
}

在上面的代码之后,我除了建议包含除“缅因州”,“马里兰州”,“马萨诸塞州”之外的所有值。但它有7个值,包括“马里兰州”,“马萨诸塞州”。我哪里做错了?请帮助。

修改 我正在使用带有.NET 3.5 sp1的dev studio 2008。我在我的asp.net mvc

的动作方法中使用上面的代码

5 个答案:

答案 0 :(得分:9)

  

在上面的代码之后,我除了建议包含除....之外的所有值

然后,怎么样:

var unqiueSugs = suggestions.Except(remQueries, StringComparer.OrdinalIgnoreCase));

不需要让你的生活变得比必要的更复杂

编辑:添加StringComparer.OrdinalIgnoreCase以获得完整性

编辑:正如我所说,你有一个空白问题。仔细看看remQueries,有一个领先的空白,比如“Maryland”而不是“Maryland”

只需使用

suggestions = suggestions.Select(s => s.Trim()).Except(remQueries.Select(s => s.Trim()), StringComparer.OrdinalIgnoreCase).ToArray();

你会没事的。

string query = "Maine, Maryland, Massachusetts, M";
var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries);

会给你这些字符串:“Maine”,“Mayland”,“Massachusetts”,“M”

答案 1 :(得分:6)

好吧,我实际上并没有这样做,但让我们阅读代码,看看它是做什么的。

        string query = "Maine, Maryland, Massachusetts, M"; 

        var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries); 

query.Trim()不执行任何操作,因为Trim从字符串的开头和结尾删除空格,而不是从字符串的中间删除空格。

分割产生一个{“Maine”,“Maryland”,“Massachusetts”,“M”}数组,分配给查询。

请注意马里兰州和马萨诸塞州的主要空间。你没有剥离这些空间。这似乎不对。

        string lastQuery = queries[queries.Length - 1].Trim(); 

lastQuery现在是“M”。数组,查询保持不变。

然后才会使用“lastQuery”。为什么这甚至在这里?这不是显示错误所必需的。

        if (queries.Length > 1) 
        { 
            var remQueries = queries.Take(queries.Length - 1).ToArray(); 

好的,现在我们有一个数组{“Maine”,“Maryland”,“Massachusetts”},它被分配给remQueries。再次注意前导空格。

            string[] suggestions = new string[] {"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",  
        "Mississippi", "Missouri", "Montana"}; 

            System.Console.WriteLine("Before Except "); 

            suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); }); 

            var unqiueSugs = from sug in suggestions 
                             where !remQueries.Any(q => q.Equals(sug, StringComparison.OrdinalIgnoreCase)) 
                             select sug; 

我注意到“独特”在这里拼写错误。

查询是“查看每个建议。删除任何与”缅因州“,”马里兰州“或”马萨诸塞州“完全相同的建议。再次注意前导空格。

            if (unqiueSugs != null) 

这是不必要的。查询对象永远不会为空。

            { 
                suggestions = unqiueSugs.ToArray(); 

执行查询。由于“缅因州”在列表中,它被过滤掉了。如果“马里兰”在列表中,它将被过滤掉,但事实并非如此。 “Maryland”和“Maryland”是不同的字符串。

            } 

            System.Console.WriteLine("\n After Except "); 
            suggestions.ToList().ForEach(str => { System.Console.WriteLine(str); });
        } 

所以结果是正确的。我怀疑你的错误是你认为“修剪”从字符串中删除所有空格。它不是。它从字符串的开头和结尾删除空格。

你不应该使用Replace来摆脱字符串中的所有空格,因为当然“New York”和“Rhode Island”可能在那里,你不希望从它们中移除空格。正确的逻辑是首先在逗号 上进行拆分,然后对所有结果元素进行修剪 。不要先做修剪!

现在,更重要的是,您自己学习如何进行这种简单的程序分析,而不是每次遇到问题都要求互联网。我建议学习如何使用调试器。仔细执行您的程序 并检查沿途的每一步,并将其与您认为正确的状态进行比较。 倾听安静的怀疑。当某些东西看起来不合时宜时,你的大脑会告诉你,就像一个意想不到的空间。听听并跟踪它。调试是一项与其他技能一样的技能;你通过练习来学习它。

答案 2 :(得分:1)

适合我:

var remQueries = new[]{"Maine", "Maryland", "Massachusetts"};
var suggestions = new[]{"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana"};
var unqiueSugs = from sug in suggestions
                 where ! remQueries.Any(q => q.Equals(sug, StringComparison.OrdinalIgnoreCase))
                 select sug;
unqiueSugs;
{ "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana" }

你的问题在别的地方。另请注意,如果您的真实列表较大,您可能会更快找到Except(自定义IEqualityComparer)。

答案 3 :(得分:1)

怎么样

var unqiueSugs = suggestions.Except(remQueries).ToArray();

答案 4 :(得分:0)

快速观察您发布的代码但是:

        string query = "Maine, Maryland, Massachusetts, M";
        var queries = query.Trim().Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries);

为您提供了4个字符串,但它们没有被调整,因为我在调试器中将鼠标悬停在查询显示上: “缅因” “马里兰” “麻省” “M”

(注意最后3个字符串前面的空格)

我确实认为以下代码是您修剪操作的原因:

var queries = query.Split((new[] { "," }), StringSplitOptions.RemoveEmptyEntries).Select(X => X.Trim()).ToArray();