1

我有一个这种类型的模型列表:

public class TourDude {
    public int Id { get; set; }
    public string Name { get; set; }
}

这是我的清单:

    public IEnumerable<TourDude> GetAllGuides {
        get {
            List<TourDude> guides = new List<TourDude>();
            guides.Add(new TourDude() { Name = "Dave Et", Id = 1 });
            guides.Add(new TourDude() { Name = "Dave Eton", Id = 1 });
            guides.Add(new TourDude() { Name = "Dave EtZ5", Id = 1 });
            guides.Add(new TourDude() { Name = "Danial Maze A", Id = 2 });
            guides.Add(new TourDude() { Name = "Danial Maze B", Id = 2 });
            guides.Add(new TourDude() { Name = "Danial", Id = 3 });
            return guides;

        }
    }

我想检索这些记录:

{ Name = "Dave Et", Id = 1 } 
{ Name = "Danial Maze", Id = 2 }
{ Name = "Danial", Id = 3 }

目标主要是折叠重复项和接近重复项(可通过 ID 确认),将尽可能短的值(比较时)作为名称。

我从哪说起呢?是否有一个完整的 LINQ 可以为我做到这一点?我需要编写一个相等比较器吗?

编辑1:

        var result = from x in GetAllGuides
                     group x.Name by x.Id into g
                     select new TourDude {
                         Test = Exts.LongestCommonPrefix(g),
                         Id = g.Key,
                     };

        IEnumerable<IEnumerable<char>> test = result.First().Test;

        string str = test.First().ToString();
4

2 回答 2

3

如果你想对项目进行分组,然后在每个组Id中找到 s 的最长公共前缀Name,那么你可以这样做:

var result = from x in guides
             group x.Name by x.Id into g
             select new TourDude
             {
                 Name = LongestCommonPrefix(g),
                 Id = g.Key,
             };

使用从这里查找最长公共前缀的算法。

结果:

{ Name = "Dave Et", Id = 1 }
{ Name = "Danial Maze ", Id = 2 }
{ Name = "Danial", Id = 3 }

static string LongestCommonPrefix(IEnumerable<string> xs)
{
    return new string(xs
        .Transpose()
        .TakeWhile(s => s.All(d => d == s.First()))
        .Select(s => s.First())
        .ToArray());
}
于 2013-05-21T16:53:10.903 回答
2

我可以通过对 ID 上的记录进行分组,然后从按名称长度排序的每个组中选择第一条记录来实现这一点:

var result = GetAllGuides.GroupBy(td => td.Id)
    .Select(g => g.OrderBy(td => td.Name.Length).First());

foreach (var dude in result)
{
    Console.WriteLine("{{Name = {0}, Id = {1}}}", dude.Name, dude.Id);
}
于 2013-05-21T16:53:59.813 回答