【问题标题】:How can I loop through an IEnumerable<string> and create another IEnumerable<string>?如何循环遍历 IEnumerable<string> 并创建另一个 IEnumerable<string>?
【发布时间】:2016-06-30 14:15:32
【问题描述】:

我有这段代码用于处理IEnumerable&lt;string&gt; 文本中的字符串

foreach (var line in text)
{
    var newLine = "";
    var ln = line.TrimStart(' ');
    var colon = line.IndexOf(":");
    if (colon != -1)
    {
        if (ln.StartsWith("adj")) newLine = "j 1" + line.Substring(colon);
        else if (ln.StartsWith("adv")) newLine = "d 1" + line.Substring(colon);
        else if (ln.StartsWith("n")) newLine = "n 1" + line.Substring(colon);
        else if (ln.StartsWith("v")) newLine = "v 1" + line.Substring(colon);
    }
    else
    {
        newLine = line;
    }
}

现在它只是循环通过IEnumerable,但我希望它创建另一个IEnumerable&lt;string&gt;,其中字符串只是newLine.Trim()的内容

谁能给我建议如何做到这一点?

【问题讨论】:

  • 你在找.Select()

标签: c# .net linq ienumerable projection


【解决方案1】:

您可以使用Select

var result = text.Select(line =>
    {
        var newLine = "";
        var ln = line.TrimStart(' ');
        var colon = line.IndexOf(":");
        if (colon != -1)
        {
            if (ln.StartsWith("adj")) newLine = "j 1" + line.Substring(colon);
            else if (ln.StartsWith("adv")) newLine = "d 1" + line.Substring(colon);
            else if (ln.StartsWith("n")) newLine = "n 1" + line.Substring(colon);
            else if (ln.StartsWith("v")) newLine = "v 1" + line.Substring(colon);
        }
        else
        {
            newLine = line;
        }
        return newLine.Trim();
    });

【讨论】:

    【解决方案2】:

    只需 yield return foreach 循环内的值。

    让你的方法返回IEnumerable&lt;string&gt;,你就会被设置:

    public IEnumerable<string> MethodX(string[] text)
    {
        foreach (var line in text)
        {
            var newLine = "";
            var ln = line.TrimStart(' ');
            var colon = line.IndexOf(":");
            if (colon != -1)
            {
            if (ln.StartsWith("adj")) newLine = "j 1" + line.Substring(colon);
                else if (ln.StartsWith("adv")) newLine = "d 1" + line.Substring(colon);
                else if (ln.StartsWith("n")) newLine = "n 1" + line.Substring(colon);
                else if (ln.StartsWith("v")) newLine = "v 1" + line.Substring(colon);
            }
            else
            {
                newLine = line;
            }
    
            yield return newLine.Trim();
        }
    }
    

    【讨论】:

    • 为什么投反对票?我的回答有什么问题?有什么改进建议吗?
    • 不是我的 DV,但方法应该采用可枚举,而不是字符串。
    【解决方案3】:
    var trimmedStrings = untrimmedStrings.Select(untrimmed => untrimmed.Trim());
    

    将此应用到您上面的代码中,

    var trimmedLines = text.Select(untrimmed => untrimmed.TrimStart(' '));
    

    但为了提高可读性,我会将整个内容放在一个函数中,其名称说明您正在做什么。这使得 main 方法更短,当您阅读它时,函数名称的行为就像一个注释。

    string ConvertToSomeOtherString(string input) //don't use this name.
    {
        var newLine = "";
        var ln = input.TrimStart(' ');
        var colon = input.IndexOf(":");
        if (colon != -1)
        {
            if (ln.StartsWith("adj")) newLine = "j 1" + input.Substring(colon);
            else if (ln.StartsWith("adv")) newLine = "d 1" + input.Substring(colon);
            else if (ln.StartsWith("n")) newLine = "n 1" + input.Substring(colon);
            else if (ln.StartsWith("v")) newLine = "v 1" + input.Substring(colon);
        }
        else
        {
            newLine = input;
        }
        return newLine.Trim();
    }
    

    现在现有方法将如下所示:

    var convertedStrings = text.Select(line => ConvertToSomeOtherString(line));
    

    之前如果有人读到这个,他们可以看到你正在用这个字符串做很多事情,但是它用这个字符串做了什么,为什么?现在他们读取了 main 方法,函数名说明了你在做什么。如果他们不关心这种转变的细节,他们可以继续阅读。如果他们关心它在做什么,他们只需要进入该功能。


    我进行了一些重构,只是想看看它会是什么样子。

    string ConvertToSomeOtherString(string input) //don't use this name.
    {
        var colonPosition = input.IndexOf(":");
        if (colonPosition == -1) return input.Trim();
        var prefix = GetPrefix(input);
        return string.IsNullOrEmpty(prefix) 
            ? string.Empty 
            : (prefix + input.Substring(colonPosition)).Trim();
    }
    
    string GetPrefix(string input) //Again, perhaps not the best name - I don't know what these are.
    {
        var trimmed = input.TrimStart(' ');
        if (trimmed.StartsWith("adj")) return "j 1";
        if (trimmed.StartsWith("adv")) return "d 1";
        if (trimmed.StartsWith("n")) return "n 1" ;
        if (trimmed.StartsWith("v")) return "v 1" ;
        return null;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 2011-06-06
      相关资源
      最近更新 更多