将最后一个非空字符串应用于空字符串?

时间:2016-12-21 14:07:51

标签: c# arrays

读入文件。查找具有带S的数字的行。维护没有S的行。保存到数组。然后我用相同数量的行填充现有的gridview。

作为占位符,我将空行设置为***这就是我被困住的地方。我需要用最后一个非空字符串填充空字符串。

例如,如果读数是:

1
2
3
Empty
Empty
Empty
4
Empty
6

我希望它显示为:

1
2
3
3
3
3
4
4
6

我无法弄清楚如何做到这一点。我一整天都在搜索示例,但只能找到抓住我阵列的第一个或最后一个数字的方法。这是我的代码。

var sLines = File.ReadAllLines(cboPartProgram.Text)
                 .Where(s => !s.StartsWith("'"))
                 .Select(s => new
                       {
                           SValue = Regex.Match(s, "(?<=S)[\\d.]*").Value,
                       })
                 .ToArray();

string LastSValue = "";
string Value = "";

for (int i = 0; i < sLines.Count(); i++)
{
     if (sLines[i].SValue == "")
     {
         LastSValue = "***";
         Value = LastSValue;
     }
     else
     {
         Value = (sLines[i].SValue);
     }
}

好的我觉得我明白了。

        for (int i = 0; i < sLines.Length; i++)
            {

            if (sLines[i].SValue == "" && i > 0)
            {
                foreach (var empt in sLines[i].SValue)
                {
                    LastSValue = sLines[i - 1].SValue;
                    Value = LastSValue;
                }
            }
            else
            {
                Value = (sLines[i].SValue);
            }

在旁注中,当我复制我的代码时,我使用上面的代码选项来格式化它,但我注意到有人总是要纠正我的间距。它直接从IDE复制,但我猜不应该每行都有间隔。我应该采取不同的方式吗?

更新

如果我应该问这个问题,请告诉我,但是它依赖于此,我认为我应该把它保留在这里。

使用上面发布的代码,我也需要它。我一直在尝试编辑这个,以便如果没有以前的编号,那么例如如果第1行没有数字但其余的数字,那么只需应用字符串"NA"否则仍然执行上面的代码对剩下的部分做了。

我想也许最好的方法就是从上面的代码中获取结果,如果还有空格,请应用"NA",但我无法理解。

3 个答案:

答案 0 :(得分:1)

在您的示例中,您只需要获取前一行的值来填充当前值。如下所示:

for (int i = 0; i < sLines.Length; i++)
{
     if (sLines[i].SValue == "" && i > 0)
     {
         sLines[i].SValue = sLines[i-1].SValue;
     }
     else
     {
         sLines[i].SValue = sLines[i].SValue;
     }
}

答案 1 :(得分:0)

根据我的理解,如果你想将结果存储在Value中并在循环中用它做其他事情(而不是在数组中更改它),你可能想要的是:

for (int i = 0; i < sLines.Count(); i++)
{
    if (sLines[i].SValue == "")
    {
        Value = LastSValue;
    }
    else
    {
        Value = (sLines[i].SValue);
        LastSValue = Value;
    }

    // use Value
}

我还建议使用sLines.Length而不是Count(),这是为事先不知道长度的序列制作的 - 它应该逐字逐句地计算元素。在这种情况下,它可能会被优化,但如果你知道你正在处理数组,那么直接询问长度是个好主意。

修改

如果没有以前的数字,要获得“NA”,只需在循环之前将LastSValue初始化为此值:

string LastSValue = "NA";

这样,如果Value为空且之前没有设置LastSValue,它仍然是“NA”。

<强> EDIT2 : 类似于@Cubi的解决方案,将其更改到位:

for (int i = 0; i < sLines.Length; i++)
{
     if (sLines[i].SValue == "")
         sLines[i].SValue = i > 0 ? sLines[i-1].SValue : "NA";
}

答案 2 :(得分:0)

您的示例还有一个问题,但目前我只关注收集“ last non empty ”字符串。

如果你看一下你的例子,你可以发现一些可能有助于你找到解决方案的东西。这些是for循环和对原始列表的引用保持不变。

对于我的示例,我将使用Linq,因为它会更容易。

首先,我将从for循环之前复制所有内容(如果有意义的话:D):

var sLines = File.ReadAllLines(cboPartProgram.Text)
     .Where(s => !s.StartsWith("'"))
     .Select(s => new
     {
         SValue = Regex.Match(s, "(?<=S)[\\d.]*").Value,
     })
     .ToArray();

string LastSValue = "";
string Value = "";

只是因为它没关系,现在可以使用。

使用for循环,我将进行修改:

for (int i = 0; i < sLines.Count(); i++)
{
    // `i` is representing current "index" of processed "word"
    // we can use this to find last "valid" element
    // string notEmpty = sLines.Take(i).LastOrDefault(word => !string.IsNullOrEmpty(word));
    // but since you want to assign this to `Value` and there can be not empty string at `i` index
    // we can make it in one line :
    Value = string.IsNullOrEmpty(sLines[i]) ? sLines.Take(i).LastOrDefault(word => !string.IsNullOrEmpty(word)) : sLines[i].SValue;
    // instead of your previous logic :
    //if (sLines[i].SValue == "")
    //{
    //    LastSValue = "***";
    //    Value = LastSValue;
    //}
    //else
    //{
    //    Value = (sLines[i].SValue);
    //}
 }

我认为你将面临的另一个问题是第一个值(通过输入判断)也可能是空的。哪个会在我的例子中抛出异常。这也不可能适合这种解决方案,因为根本没有先前的价值。