Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ:转换可枚举项直到满足结束条件,如果满足结束条件则返回_C#_Linq_Out - Fatal编程技术网

C# LINQ:转换可枚举项直到满足结束条件,如果满足结束条件则返回

C# LINQ:转换可枚举项直到满足结束条件,如果满足结束条件则返回,c#,linq,out,C#,Linq,Out,我有一个可枚举的字符串strArr。我希望尽可能将所有条目转换为int,当条目不能转换为int时,枚举应停止。我还想返回一个bool,告诉我是否可以转换所有条目 所以我要寻找的是int.TryParse的可枚举版本(如果转换成功,它将返回bool和转换后的值) 我以为可以用LINQ完成,但我想不出来。以下是我的想法: strArr. Select(s => { bool b = int.TryParse(s, out int i); return (i, b); }).

我有一个可枚举的字符串
strArr
。我希望尽可能将所有条目转换为
int
,当条目不能转换为
int
时,枚举应停止。我还想返回一个
bool
,告诉我是否可以转换所有条目

所以我要寻找的是
int.TryParse
的可枚举版本(如果转换成功,它将返回bool和转换后的值)

我以为可以用LINQ完成,但我想不出来。以下是我的想法:

strArr.
    Select(s => { bool b = int.TryParse(s, out int i); return (i, b); }).
        // returns both the converted int value and the parsing bool for each entry
    TakeWhile(ib => ib.b).
        // will stop when the first parsing bool was false
    Select(ib => i).ToArray();
        // will only take the ints from the (int, bool) pairs and return an array
此解决方案将把转换的条目作为数组提供给我,但它不会告诉我转换是否成功。我需要一种方法来
输出布尔值或可枚举值,但是如何


我知道我可以比较
strArr
的长度和返回的int数组,看看转换是否成功。但我想了解LINQ的使用情况,而不仅仅是解决手头的问题(我总是可以做一些循环,根本不使用LINQ)。

多亏mjwills的一点提示,我明白了:

bool parseSuccess = true;
int[] intArr = strArr.
    Select(s => { parseSuccess &= int.TryParse(s, out int i); return i; }).
    TakeWhile(i => parseSuccess).ToArray();

多亏了mjwills的小小暗示,我明白了:

bool parseSuccess = true;
int[] intArr = strArr.
    Select(s => { parseSuccess &= int.TryParse(s, out int i); return i; }).
    TakeWhile(i => parseSuccess).ToArray();

应该避免从lambda内部对变量进行变异,因为这会导致相当脆弱的代码

您可以创建自己的
TakeWhilePlusOne
方法,该方法为您提供第一个未通过谓词的条目,如下所示:

static class EnumerableExt {
    public static IEnumerable<TSource> TakeWhilePlusOne<TSource>(
        this IEnumerable<TSource> source
    ,   Func<TSource,bool> predicate
    ) {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (predicate == null) throw new ArgumentNullException(nameof(predicate));
        return TakeWhilePlusOneIterator<TSource>(source, predicate);
    }

    static IEnumerable<TSource> TakeWhilePlusOneIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        foreach (TSource element in source) {
            var stop = !predicate(element);
            yield return element;
            if (stop) {
                break;
            }
        }
    }
}
您还可以使用(感谢您的评论):


应该避免从lambda内部对变量进行变异,因为这会导致相当脆弱的代码

您可以创建自己的
TakeWhilePlusOne
方法,该方法为您提供第一个未通过谓词的条目,如下所示:

static class EnumerableExt {
    public static IEnumerable<TSource> TakeWhilePlusOne<TSource>(
        this IEnumerable<TSource> source
    ,   Func<TSource,bool> predicate
    ) {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (predicate == null) throw new ArgumentNullException(nameof(predicate));
        return TakeWhilePlusOneIterator<TSource>(source, predicate);
    }

    static IEnumerable<TSource> TakeWhilePlusOneIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
        foreach (TSource element in source) {
            var stop = !predicate(element);
            yield return element;
            if (stop) {
                break;
            }
        }
    }
}
您还可以使用(感谢您的评论):



在LINQ设置为
true
之前,有一个
wassucture
bool变量。在菜单中选择do
wassucture=wassucture&&b
(实际上,由于您的
TakeWhile
,即使是
wassucture=b;
也可以工作)。检查
wassucture
的值以查看是否所有值都成功转换。我不确定这意味着什么:
选择(ib=>I)
。在这个上下文中没有
i
。您是否只想从
ib
对象中选择整数?如果只选择整数,那么这就解释了为什么在结果数组元素上没有得到
bool
属性
ib
包含解析的
int
bool
。这不是你要找的吗?虽然这看起来很奇怪,因为对于每个数组元素,生成的
bool
总是
true
。“但它不会告诉我转换是否成功”-如果有转换结果,则这些元素的转换是成功的。我不完全清楚你在这里找什么。您的起始数据是什么?数据的成功结果是什么?您已经在第一次选择中返回了元组,为什么不在最后一次选择中执行相同的操作?@mjwills:OP已经拥有该信息,并且已经知道如何观察它。如果生成的集合小于原始集合,则并非所有元素都已转换。这看起来像是试图彻底地将简单的
if
语句过度复杂化。即使在转换中设置了
bool
,也需要在转换后编写
if
语句来检查
bool
。那么这样做可以保存什么呢?在LINQ设置为
true
之前,使用
wassucture
bool变量。在菜单中选择do
wassucture=wassucture&&b
(实际上,由于您的
TakeWhile
,即使是
wassucture=b;
也可以工作)。检查
wassucture
的值以查看是否所有值都成功转换。我不确定这意味着什么:
选择(ib=>I)
。在这个上下文中没有
i
。您是否只想从
ib
对象中选择整数?如果只选择整数,那么这就解释了为什么在结果数组元素上没有得到
bool
属性
ib
包含解析的
int
bool
。这不是你要找的吗?虽然这看起来很奇怪,因为对于每个数组元素,生成的
bool
总是
true
。“但它不会告诉我转换是否成功”-如果有转换结果,则这些元素的转换是成功的。我不完全清楚你在这里找什么。您的起始数据是什么?数据的成功结果是什么?您已经在第一次选择中返回了元组,为什么不在最后一次选择中执行相同的操作?@mjwills:OP已经拥有该信息,并且已经知道如何观察它。如果生成的集合小于原始集合,则并非所有元素都已转换。这看起来像是试图彻底地将简单的
if
语句过度复杂化。即使在转换中设置了
bool
,也需要在转换后编写
if
语句来检查
bool
。那么这样做会保存什么呢?如果
strArr
为空,则返回
true
——这就是您想要的吗?可能吧,我只是澄清一下。是的,这是正确的。在空字符串数组中,没有任何东西会导致转换失败,因此没有理由返回
false
。虽然这会起作用,但我个人不喜欢在linq语句中对局部变量产生副作用。linq是函数式编程,它有点违反它,因为它有副作用。我没有真正看到它的好处。在此转换之后,您仍然需要检查结果。您试图避免编写
if
语句来比较