Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ-介于“a”和“e”之间_C#_Linq - Fatal编程技术网

C# LINQ-介于“a”和“e”之间

C# LINQ-介于“a”和“e”之间,c#,linq,C#,Linq,我有一份学生的一般名单。我想在LINQ的帮助下过滤从a到e开始的学生姓名 Students = Students.Where(s => s.Name.Substring(0, 1) == "a" && s.Name.Substring(0, 1) == "e").ToList(); 请帮助我做到这一点。范围由更小/更大定义,而不仅仅是==: Students = Students.Where(s => s.

我有一份学生的一般名单。我想在LINQ的帮助下过滤从a到e开始的学生姓名

Students = Students.Where(s => s.Name.Substring(0, 1) == "a" 
                            && s.Name.Substring(0, 1) == "e").ToList();

请帮助我做到这一点。

范围由更小/更大定义,而不仅仅是==:

 Students = Students.Where(s => s.Name.Substring(0, 1) >= "a" 
                        && s.Name.Substring(0, 1) <= "e").ToList();

您可能还希望使用小写字母或与这两种情况进行比较。

未经此测试可能会起作用:

Students = Students.Where(s => s.Name.Substring(0, 1) >= "a" 
                        && s.Name.Substring(0, 1) <= "e").ToList();

有多种方法可以做到这一点。这里有两个:

您仍然可以使用原始代码,但可以将相等性检查转换为范围检查:


我会用你提供的信息来做这件事

var s = new [] {"a","b","c","d","e"};
Students = Students.Where(s => s.Contains(s.Name.Substring(0, 1))).ToList();

希望我理解正确

Students = Students.Where(s => {
   char c = s.Name[0];
   return (c >= 'a' && c <= 'e') || (c >= 'A' && c <= 'E') ;
}).ToList();

我还包括了大写字母。

在不使用其他字符串操作方法的情况下,最简单的方法之一是:

var filter = Students.Where(s => s!= null && s [0] >= 'a' && s[0] <= 'e').ToList();
您可以使用string.CompareOrdinal方法


它将包括a和e。您可以在比较之前使用大写转换,也可以用于不区分大小写的比较。

为此,我将添加一个方法,将字符强制转换为可以比较的整数:

private static bool StartsWithRange(string value, char first, char last)
{
  if (string.IsNullOrEmpty(value))
  {
    return false;
  }

  if (first > last)
  {
    throw new ArgumentException(string.Format("'{0}' shouldn't come after '{1}'.", first, last), nameof(last));
  }

  int intValue = value.ToLower()[0];
  return intValue >= first && intValue <= last;
}
我测试了不同的案例,似乎有效:

Assert.IsFalse(StartsWithRange("abcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("dcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("Dcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("ebcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("Ebcd", 'd', 'e'));
Assert.IsFalse(StartsWithRange("fbcd", 'd', 'e'));
Assert.IsFalse(StartsWithRange("Fbcd", 'd', 'e'));
Assert.IsFalse(StartsWithRange(string.Empty, 'd', 'e'));
请注意ToLower调用,如果不是所有值都在同一情况下,则需要此调用


如果值都在一行中,如果它们只是随机字母,那么我将使用上述数组方法。

我希望您使用正则表达式

students = students.Where(x => Regex.IsMatch(x.Name, @"^[a-e].*", RegexOptions.IgnoreCase) == true).ToList();
在这里你可以看到,我使用正则表达式@^[a-e].*来表示我们必须对以a、b、c、d、e开头的学生姓名进行命名。因此,您可以轻松地修改过滤器以获得学生


注意:请使用System.Text.RegularExpressions包含名称空间;在项目中使用正则表达式。

我会考虑在扩展方法之间实现一个并使用它。 代码示例:

    public void Main()
    {
        var names = new string[] { "andy", "lisa", "zoro", "billy" };

        var result = FilterBetween(names, 'a', 'e');
    }

    public IEnumerable<string> FilterBetween(IEnumerable<string> names, char start, char end)
    {
        return names.
            Where(name => name.
                First().
                Between(start, end));
    }



public static class ExtensionMethods
{
    public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
    {
        return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) <= 0;
    }
}

@Jesuraja,所以,以b或c开头的学生姓名应该从您的查询中获取。是吗?你最好考虑一下SopPiSon的不敏感性。名字很可能从大写字母开始。“是的,绝对的。”Jesuraja,我更喜欢你用正则表达式。请看我的答案。对A和A来说,确实重要,您可以使用s.Name.Substring0、1.ToLower或s.Name[0]。ToLowerI实际上考虑的是sql,但问题是“just”linq,因此在代码中它确实很重要。刚刚在mssql中测试了它,它考虑了排序,这很好。感谢您的回复。我非常喜欢使用单元测试框架来列出测试用例。
Students = Students.Where(s => 
string.CompareOrdinal(s.Name.Substring(0, 1), "a") >= 0 && string.CompareOrdinal(s.Name.Substring(0, 1), "e") <= 0)
.ToList();
private static bool StartsWithRange(string value, char first, char last)
{
  if (string.IsNullOrEmpty(value))
  {
    return false;
  }

  if (first > last)
  {
    throw new ArgumentException(string.Format("'{0}' shouldn't come after '{1}'.", first, last), nameof(last));
  }

  int intValue = value.ToLower()[0];
  return intValue >= first && intValue <= last;
}
Students.Where(s => StartsWithRange(s, 'a', 'e')).ToList();
Assert.IsFalse(StartsWithRange("abcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("dcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("Dcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("ebcd", 'd', 'e'));
Assert.IsTrue(StartsWithRange("Ebcd", 'd', 'e'));
Assert.IsFalse(StartsWithRange("fbcd", 'd', 'e'));
Assert.IsFalse(StartsWithRange("Fbcd", 'd', 'e'));
Assert.IsFalse(StartsWithRange(string.Empty, 'd', 'e'));
students = students.Where(x => Regex.IsMatch(x.Name, @"^[a-e].*", RegexOptions.IgnoreCase) == true).ToList();
    public void Main()
    {
        var names = new string[] { "andy", "lisa", "zoro", "billy" };

        var result = FilterBetween(names, 'a', 'e');
    }

    public IEnumerable<string> FilterBetween(IEnumerable<string> names, char start, char end)
    {
        return names.
            Where(name => name.
                First().
                Between(start, end));
    }



public static class ExtensionMethods
{
    public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
    {
        return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) <= 0;
    }
}