【问题标题】:Replace empty string with null in array efficiently有效地将数组中的空字符串替换为空字符串
【发布时间】:2016-04-21 01:56:00
【问题描述】:

我想知道用空值替换数组中的空字符串的最有效方法。

我有以下数组:

string[] _array = new string [10];
_array[0] = "A";
_array[1] = "B";
_array[2] = "";
_array[3] = "D";
_array[4] = "E";
_array[5] = "F";
_array[6] = "G";
_array[7] = "";
_array[8] = "";
_array[9] = "J";

我目前正在用以下内容替换空字符串:

for (int i = 0; i < _array.Length; i++)
{
    if (_array[i].Trim() == "")
    {
        _array[i] = null;
    }
}

这在小型数组上运行良好,但我正在寻找一些在完成任务时最有效的代码,因为我正在使用的数组可能要大得多,我会一遍又一遍地重复这个过程。

有没有 linq 查询或者更高效的方法?

【问题讨论】:

    标签: c# arrays linq


    【解决方案1】:

    您可以考虑将_array[i].Trim() == ""string.IsNullOrWhitespace(_array[i]) 切换以避免新的字符串分配。但这几乎是您可以做的所有事情,以使其更快并且仍然保持顺序。 LINQ 不会比 for 循环快。

    您可以尝试使您的处理并行化,但这似乎是一个更大的变化,因此您应该评估这在您的场景中是否可行。

    Parallel.For(0, _array.Length, i => {
        if (string.IsNullOrWhitespace(_array[i]))
        {
            _array[i] = null;
        }
    });
    

    【讨论】:

      【解决方案2】:

      就效率而言,它很好,但它也取决于数组的大小以及您在此类数组上迭代的频率。我看到的主要问题是您可以使用trim 方法获得NullReferenceException。更好的方法是使用string.IsNullOrEmptystring.IsNullOrWhiteSpace,后者更符合您的要求,但并非在所有.net 版本中都可用。

      for (int i = 0; i < _array.Length; i++)
      {
          if (string.IsNullOrWhiteSpace(_array[i]))
          {
              _array[i] = null;
          }
      }
      

      【讨论】:

      • 您将不再需要.Trim()
      • @JanR - 谢谢,我没有在我的改动中发现这一点,这就是我回答的重点:)
      • 我无法想象你能得到比这更快的速度,除非你使用本机代码并进行汇编!或者您自己在循环中实现 IsNullOrWhiteSpace 以保存 Call 指令。 IsNulOrWhitespace 的代码在这里referencesource.microsoft.com/#mscorlib/system/…
      • @PaulBartlett - 唯一可以做的就是使用像 MarcinJuraszek 提议的 TPL 库。除此之外,我同意,这可能是最好的。
      【解决方案3】:

      LINQ 主要用于查询而不是赋值。要对 Collection 执行某些操作,您可以尝试使用List。如果你使用List 而不是Array,你可以用一行来代替:

      _list.ForEach(x => string.IsNullOrWhiteSpace(x) ? x = null; x = x);
      

      【讨论】:

      • 代码更少,但实际上会比数组+for循环慢。
      【解决方案4】:

      linq 查询将在后台执行基本相同的操作,因此您不会仅仅通过使用 linq 来获得任何真正的效率。

      在确定更有效的方法时,请注意以下几点:

      1. 您的阵列将增长到多大?
      2. 数组中的数据多久会更改一次?
      3. 阵列的顺序重要吗?

      您已经回答说您的阵列可能会增长到大尺寸并且性能是一个问题。

      因此,同时查看选项 2 和 3,如果您的数据顺序无关紧要,那么您可以保持数组排序并在检测到非空字符串后中断循环。

      理想情况下,您可以在输入的过程中检查数据,这样您就不必不断地循环遍历整个数组。这不可能吗?

      希望这至少能引起一些想法。

      【讨论】:

        【解决方案5】:

        这很难看,但是您可以使用以下代码消除 RTL 的 CALL 指令,正如我之前提到的:

        if (_array[i] != null) {
          Boolean blank = true;
          for(int j = 0; j < value.Length; j++) {
            if(!Char.IsWhiteSpace(_array[i][j])) { 
                blank = false;
                break;
            }
          }
        
          if (blank) {
            _array[i] = null;
          }
        }
        

        但它确实添加了一个额外的任务并包含一个额外的条件,这对我来说太难看了。但是,如果您想从大量列表中减少纳秒,那么也许可以使用它。我喜欢并行处理的想法,你可以用 Parallel 来包装它。

        【讨论】:

          【解决方案6】:

          使用下面的代码

          _array = _array.Select(str => { if (str.Length == 0) str = null; return str; }).ToArray();
          

          【讨论】:

          • 上面代码sn-p中也可以使用string.IsNullOrWhitespace(str)代替str.length ==0
          猜你喜欢
          • 2014-11-12
          • 1970-01-01
          • 1970-01-01
          • 2013-01-04
          • 1970-01-01
          • 1970-01-01
          • 2018-12-04
          • 1970-01-01
          • 2014-08-10
          相关资源
          最近更新 更多