如何使用LINQ返回字符串第一部分的最长匹配

本文关键字:一部分 第一部 何使用 LINQ 返回 字符串 | 更新日期: 2023-09-27 17:59:40

假设我有以下对象:

public struct Lookup {
    public string code;
    public string name;
}
public static List<Lookup> lookup =new List<Lookup>() {
    new Lookup {
        code = "12345",
        name = "abc"
    },
    new Lookup {
        code = "123",
        name = "def"
    },
    new Lookup {
        code = "123456",
        name = "ghi"
    }
};
public static Lookup FindMatch(string valueToSearchInLinq) {
    // Find the first result or null if no match found
    var result = lookup.FirstOrDefault( x => x );
    return result;
}

运行以下程序时:

List<string> searchFor = new List<string>() { "123111117", "123456123", "12159785" };
foreach(var s in searchFor) {
   var r = FindMatch(s);
   if(r.code == null) {
       System.Diagnostics.Debug.WriteLine(string.Format("No match for {0}", s));
   } else {
       System.Diagnostics.Debug.WriteLine( string.Format( "{0} is {1}", s, r.name ) );
   }
}

它应该产生以下结果:

  • 123111117是def
  • 123456123是ghi
  • 12159785没有对手

我遇到了如何在FindMatch方法中的var result = lookup.FirstOrDefault( x => x );行上编写LINQ查询以实现此目标的问题。

目前,我在一个巨大的for循环中使用开关盒来按降序检查数字的长度(例如,检查"123456123",然后是"12345612",再是"1234561"等等),直到找到匹配项。我想利用LINQ的强大功能,因为我发现它的循环处理速度比传统的foreach()快得多。

如何使用LINQ返回字符串第一部分的最长匹配

如何使用LINQ返回第一部分的最长匹配字符串

正如许多评论所建议的那样,您可以依靠匹配计数。既然你想匹配第一部分,我建议使用StartWith

public static Lookup FindMatch(string valueToSearchInLinq)
{
    // Find the first result or null if no match found
    var result = lookup.Select(x=> new {x, count = valueToSearchInLinq.StartsWith(x.code)? x.code.Length : -1})
                       .OrderByDescending(x=>x.count);
    // Check for any single match.
    return result.All(x=>x.count <0)? new Lookup() : result.First().x;
}

// Input
List<string> searchFor = new List<string>() { "123111117", "123456123", "12159785" };
// You get this output
123111117 is def
123456123 is ghi
No match for 12159785

一个技巧是,有一个重载的方法可以接受比较类型,如果你想忽略case等,可以探索这个选项

检查此Demo