我正在寻找一种使用 linq 制作唯一列表的方法
原始列表
Level 01
Level 01
-- Blank Line --
Level 02
Level 02
-- Blank Line --
Level 03
Level 03
-- Blank Line --
Level 04
Level 04
等等
我想做什么:
Level 01
-- Blank Line --
Level 02
-- Blank Line --
Level 03
-- Blank Line --
Level 04
谢谢
答案 0 :(得分:1)
您可以使用 Enumerable.Aggregate
:
string blankLine = // whatever a blank line is
var list = new List<string>
{
"Level 01",
"Level 01",
blankLine,
"Level 02"
"Level 02"
blankLine,
// ...
};
var unique = list
.Aggregate(
Enumerable.Empty<string>(), // Initial accumulator value
(acc, x) => x == blankLine || !acc.Contains(x) ? acc.Append(x) : acc);
答案 1 :(得分:0)
您的说明不完整。你想用这个输入做什么:
Level 01
Level 02
-- Blank Line --
Level 03
Level 04
-- Blank Line --
那么两个连续的空行怎么样?
Level 01
Level 01
-- Blank Line --
-- Blank Line --
Level 02
如果您的输入序列为空,您想要什么?一个空的输出,还是只有一个空行?
假设你没有这个。您的要求是:
<块引用>给定一个输入字符串序列,没有两个连续的空行。取第一个字符串,跳过所有字符串直到第一个空字符串。取空字符串。重复此操作直到序列结束。
所以你取第一个“Level 01”,跳过所有行直到空行,你取空行,然后第一行:“Level 02”。跳过所有行直到下一个空行,取下一个空行,依此类推
“空字符串”实际上可能是“--空白行--”。我假设您足够聪明,可以相应地更改代码。
你可以在一个大的 LINQ 语句中做到这一点。我认为如果您制作扩展方法,您的代码将更易于阅读、理解、重用、测试和维护。如果您不熟悉扩展方法,请参阅 extension methods demystified
static IEnumerable<string> SkipContiguousLines(this IEnumerable<string> source)
{
// TODO implement
}
我们先看看界面是不是你想要的:
IEnumerable<string> lines = ... // get the input
IEnumerable<string> remainingLines = lines.SkipContiguous();
或者在更大的 LINQ 中:
var result = orderLines.GroupBy(orderLine => orderLine.OrderId)
.Select(group => new
{
OrderId = group.Key,
OrderLines = group.SkipContiguous(),
});
代码相当简单:
static IEnumerable<string> SkipContiguousLines(this IEnumerable<string> lines)
{
string blankLine = String.Empty; // or ----- Blank Line ---- ?
using (var lineIterator in lines.GetEnumerator())
{
bool lineAvailable = lineIterator.MoveNext();
while (lineAvailable)
{
// there is still something in your input:
yield return lineIterator.Current;
// skip until blank line:
while (lineAvailable && lineIterator.Current != blankLine)
{
lineAvailable = lineIterator.MoveNext();
}
// if not at end, you found a blank line: return the blank line
if (lineAvailable) yield return blankLine;
}
}
}