Aggregate String []抓住第一个不同的,但我希望它抓住最后一个不同的

时间:2013-06-25 02:39:05

标签: c# linq aggregate

我有一个像这样的字符串 string dir =“video / video / About / video / video /”

当我运行分割并通过我的linq语句运行时,它抓住了第一个不同的项目,所以视频/关于但我想让它抓住最后一个可能的区别。所以关于/视频

所以“视频/视频/关于/视频/视频/”应该等于关于/视频

但“视频/视频/关于/关于”仍然应该等于视频/关于

repeat = domain + dir.Split('/')
.Where(x => keep.Contains(x)).Distinct()
.Aggregate((gi, j) => gi + "/" + j) + repeat.Substring(lastSlash);

2 个答案:

答案 0 :(得分:3)

您可以尝试Reverse两次:

string result = domain + dir.Split('/')
        .Where(x => keep.Contains(x))
        .Reverse() //once before Distinct
        .Distinct()
        .Reverse() //and again afterwards
        .Aggregate((gi, j) => gi + "/" + j) + repeat.Substring(lastSlash);

所以video/video/About/video/video/结果为About/video/

video/video/About/About结果为video/About/

答案 1 :(得分:1)

考虑使用Select的重载,它将索引作为转换的一部分(记录为here)。

如果您想要每个不同元素的最后一个不同元素,您可以尝试相应地使用GroupBy每个IGrouping的顺序,并抓住每个组的正确元素。

repeat = domain + dir.Split('/')
.Select((word, index) => Tuple.Create(word, index))
.Where(x => keep.Contains(x.Item1))
.GroupBy(x => x.Item1)
.Select(g => g.OrderByDescending(x => x.Item2).First())
.OrderBy(x => x.Item2)
.Select(x => x.Item1)
.Aggregate((gi, j) => gi + "/" + j) + repeat.Substring(lastSlash);

在这里,我们将每个单词与其索引相结合(使用上面提到的Select重载)。然后我们过滤到感兴趣的词。我们现在使用Distinct生成GroupBy,而不是使用IEnumerable<IGrouping<string, Tuple<string, int>>。由于IGrouping本身实现了IEnumerable,因此我们通过在按索引排序时获取每个IGroupings的最后一个元素,将Tuple<string, int>列表投影到IGrouping列表。然后我们按索引排序Tuples的新列表,以便单词保持顺序,并投射到元组的string部分。