【问题标题】:Replace a specific item in IEnumerable<string>替换 IEnumerable<string> 中的特定项目
【发布时间】:2015-06-24 22:33:54
【问题描述】:

我是 C# 新手,正在处理 IEnumerable。我想替换 IEnumerable 中的特定项目。例如。

IEnumerable<string> m_oEnum = new string[] {"abc","def","ghi", "abcdef"};

我只想将字符串“abc”替换为“abc-test”,而不是更改“abcdef”。

【问题讨论】:

  • m_oEnum 必须是 IEnumerable 吗?你会知道每次你打算改变的元素的索引位置吗?
  • 你总是知道位置,还是你总是知道确切的值?
  • 试试这个m_oEnum.Select(s =&gt; s.Equals("abc") ? "abc-test" : s);
  • 您不能在IEnumerable 的实例中替换in 中的项目。您可以替换实现该接口的某些类型的类的实例中的项目(修改集合),并且您可以生成新的枚举,其中根据某些标准替换一个或多个项目。请澄清您的问题,以便清楚您要做什么。

标签: c# search replace ienumerable


【解决方案1】:

为什么不使用扩展方法?

考虑以下代码:

        var intArray = new int[] { 0, 1, 1, 2, 3, 4 };
        // Replaces the first occurance and returns the index
        var index = intArray.Replace(1, 0);
        // {0, 0, 1, 2, 3, 4}; index=1

        var stringList = new List<string> { "a", "a", "c", "d"};
        stringList.ReplaceAll("a", "b");
        // {"b", "b", "c", "d"};

        var intEnum = intArray.Select(x => x);
        intEnum = intEnum.Replace(0, 1);
        // {0, 0, 1, 2, 3, 4} => {1, 1, 1, 2, 3, 4}
  • 没有代码重复
  • 无需输入长 linq 表达式
  • 无需额外使用

源代码:

namespace System.Collections.Generic
{
    public static class Extensions
    {
        public static int Replace<T>(this IList<T> source, T oldValue, T newValue)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            var index = source.IndexOf(oldValue);
            if (index != -1)
                source[index] = newValue;
            return index;
        }

        public static void ReplaceAll<T>(this IList<T> source, T oldValue, T newValue)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            int index = -1;
            do
            {
                index = source.IndexOf(oldValue);
                if (index != -1)
                    source[index] = newValue;
            } while (index != -1);
        }


        public static IEnumerable<T> Replace<T>(this IEnumerable<T> source, T oldValue, T newValue)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            return source.Select(x => EqualityComparer<T>.Default.Equals(x, oldValue) ? newValue : x);
        }
    }
}

已添加前两个方法来更改引用类型的对象。当然,您可以对所有类型只使用第三种方法。

另一个问题的答案相同:https://stackoverflow.com/posts/38728879/edit

【讨论】:

    【解决方案2】:

    要构建 Tim Schmelter 的答案,您可以像这样使用现有代码来实现,注意您不需要将变量声明为 IEnumerable&lt;string&gt;

    var m_oEnum = new string[] { "abc", "def", "ghi", "abcdef" };
    m_oEnum = m_oEnum.Select(s => s == "abc" ? "abc-test" : s).ToArray();
    

    【讨论】:

      【解决方案3】:

      试试类似的东西

      m_oEnum.ToList()[0]="abc-test";
      

      【讨论】:

      • 它不起作用。您创建一个列表,但不要更改原始值。
      【解决方案4】:

      如果您的意图是更新数组中的特定值,并且您将知道要更新的项目的索引:

      var itemIndex = 0
      var m_oEnum = new string[] { "abc", "def", "ghi", "abcdef" };
      m_oEnum[itemIndex] = "abc-test"
      

      否则,其他答案将达到相同的效果。请注意,源数组变量实际上不会以这种方式改变。

      【讨论】:

      • 这并不能回答 OP 的问题..您在这里所做的只是根据单个索引更改值..如果在不同的位置有许多 abc stings 怎么办..然后呢。 .?
      • 认为我们都在猜测......但我对这个问题的解释是如何更改数组中项目的值 - “替换”特定项目,OP 说......但是,如果一个方法接受项目索引的参数 - 那么上面的代码将完成任务。
      • 很公平..但我的意思是如果有 2 个字符串位于 2 个不同的索引位置..那么这不是一个非常理想的编码方式.. 多思考动态方式或如果位置不固定怎么办..有时您必须跳出框框思考..因为在编程世界中,注意永远是静态的..关于永不改变..编程世界中的事情总是在变化..
      • 我完全同意,我向 OP 提出了这个问题:索引是否已知。我的回答按照措辞来说明问题,尽管这种情况可能不太可能,并建议如果问题的措辞不正确,另一个答案将更加动态。感谢您的反馈!
      【解决方案5】:
      m_oEnum  = m_oEnum.Select(s => s == "abc" ? "abc-test" : s).ToArray();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多