C# LINQ-介于“a”和“e”之间
我有一份学生的一般名单。我想在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.
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;
}
}