给出如下序列: -
var list = new[] {"1a", "1b", "1c", "1d", "2a", "3a", "4a", "4b", "5a", "6a", "7a", "7b", "8a"}.Select(x => new { P1 = x.Substring(0,1), P2 = x.Substring(1,1)});
我想删除"中间"中的重复项。最终: -
var expected = new[] {"1a", "1d", "2a", "3a", "4a", "4b", "5a", "6a", "7a", "7b", "8a"}.Select(x => new { P1 = x.Substring(0, 1), P2 = x.Substring(1, 1) });
因此,任何超过两次的重复都会被删除。尽管我获得了第一个和最后一个复制品,这一点非常重要。
答案 0 :(得分:1)
对于那些没有聚合并想要使用闭包的超短答案的人:
var data = new[] { "1a", "1b", "1c", "1d", "2a", "3a", "4a", "4b", "1e", "5a", "6a", "7a", "7b", "8a" };
char priorKey = ' ';
int currentIndex = 0;
var result2 = data.GroupBy((x) => x[0] == priorKey ? new { k = x[0], g = currentIndex } : new { k = priorKey = x[0], g = ++currentIndex })
.Select(i => new[] { i.First(), i.Last() }.Distinct())
.SelectMany(i => i).ToArray();
给@Slai提供基于的代码的提示(我为非连续组问题添加了一个修复程序。)
以下是使用Aggregate的方法。 我没有测试所有边缘情况......只是你的测试用例。
var list = new[] { "1a", "1b", "1c", "1d", "2a", "3a", "4a", "4b", "5a", "6a", "7a", "7b", "8a" }
.Aggregate(new { result = new List<string>(), first = "", last = "" },
(store, given) =>
{
var result = store.result;
var first = store.first;
var last = store.last;
if (first == "")
// this is the first one.
first = given;
else
{
if (first[0] == given[0])
last = given;
else
{
result.Add(first);
if (last != "")
result.Add(last);
first = given;
last = "";
}
}
return new { result = result, first = first, last = last }; },
(store) => { store.result.Add(store.first); if (store.last != "") store.result.Add(store.last); return store.result; })
.Select(x => new { P1 = x.Substring(0,1), P2 = x.Substring(1,1)});
到目前为止,我创建了一个对象来保存列表,以及到目前为止已知的第一个和最后一个。
然后我只使用逻辑来移除中间的东西。
答案 1 :(得分:1)
按第一个字符分组,并取每组的第一个和最后一个项目:
var list = "1a 1b 1c 1d 2a 3a 4a 4b 5a 6a 7a 7b 8a".Split();
var result = list.GroupBy(i => i[0])
.Select(i => new[] { i.First(), i.Last() }.Distinct())
.SelectMany(i => i).ToArray();
Debug.Print(string.Join("\", \"", result));
// { "1a", "1b", "1c", "1d", "2a", "3a", "4a", "4b", "5a", "6a", "7a", "7b", "8a" }