我想制作一个简单的CSV解析器。它应该通过逗号分隔值列表并将它们放在IList<int>
中。这些值应该是整数。如果值不可解析,我只想省略它。
这是我到目前为止的代码:
csv.Split(',').Select(item =>
{
int parsed;
if (int.TryParse(item, out parsed))
{
return parsed;
}
continue; //is not allowed here
}).ToList();
但是,此处不允许使用continue
(当然)。 如何在我的select实现中省略一个值?
注意:我当然可以使用foreach或LINQ表达式,但我想知道如何使用lambda。
答案 0 :(得分:9)
怎么样:
public static IEnumerable<int> ExtractInt32(this IEnumerable<string> values) {
foreach(var s in values) {
int i;
if(int.TryParse(s, out i)) yield return i;
}
}
然后:
var vals = csv.Split(',').ExtractInt32().ToList();
这里的好东西:
int.MinValue
)答案 1 :(得分:2)
Select
会转换一个值。它没有过滤。 Where
正在这样做:
csv.Split(',')
.Select(item =>
{
int parsed;
return new { IsNumber = int.TryParse(item, out parsed),
Value = parsed };
})
.Where(x => x.IsNumber)
.Select(x => x.Value);
此外,请参阅this answer这是一个聪明,简短的方法。请注意&#34;聪明&#34;的含义在这里并不完全正面。
答案 2 :(得分:1)
我认为你有三种选择:
SelectMany
代替您将允许您为要省略的元素返回空的可枚举(否则将返回长度为1的可枚举)。-1
)来表示“省略”,然后将其过滤掉。这种方法很脆弱,因为您可能会选择随后出现在集合中的值,这将导致细微的错误。 (您可以通过使用更大的数据类型来缓解此问题,例如long
并选择int
范围之外的值,但随后您需要转换回int
。)Nullable<int>
(int?
)代替,然后过滤掉null
值。1:
csv.Split(',').SelectMany(item =>
{
int parsed;
if (int.TryParse(item, out parsed))
{
return new[] {parsed};
}
return Enumerable.Empty<int>();
}
3:
csv.Split(',').Select(item =>
{
int parsed;
if (int.TryParse(item, out parsed))
{
return (int?) parsed;
}
return (int?) null;
}
.Where(item => item.HasValue)
.Select(item => item.Value);
答案 3 :(得分:1)
一种方法是返回一些默认值,然后跳过它。
errorInt = int.MinValue;
csv.Split(',').Select(item =>
{
int parsed;
if (int.TryParse(item, out parsed))
{
return parsed;
}
else
{
return errorInt;
}
}).Where(val => val != errorInt).ToList();
答案 4 :(得分:1)
试试这个:
int dummy;
sv.Split(',').Where(c => int.TryParse(c,out dummy)).Select(c => int.Parse(c));
int.TryParse(..)
只是检查它是否是要转换为int的有效字符串。 out参数只是被忽略了 - 我们需要它。
我们知道只有那些“使它成为”Select()
的字符串值才能被安全地解析为int。
答案 5 :(得分:0)
我可能只会使用:
csv.Split(',').Where(item => isValid(item)).Select(item => TransformationExpression(item));
,或者
csv.Split(',').Select(item => ReturnsDummyValueIfInvalid(item)).Where(item => item != DummyValue);
答案 6 :(得分:0)
int TempInt;
List<int> StuffIWant = csv.Split(',').Where(item => int.TryParse(item, TempInt)).ToList();
答案 7 :(得分:0)
为什么不在数组上使用Where
,然后才选择正确的整数
csv.Split(',')
.Where(item =>
{
int parsed;
return int.TryParse(item, out parsed);
})
.Select(item => Convert.ToInt32(item));