1

I am new to C# and dealing with IEnumerable. I want to replace a specific item in IEnumerable. E.g.

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

I only want to replace the string "abc" with "abc-test", but not change "abcdef".

Romonov
  • 8,145
  • 14
  • 43
  • 55
  • does m_oEnum have to be an IEnumerable? and will you know the index position of the element you intend to change every time? – diegohb Apr 17 '15 at 21:51
  • Do you always know the position, or do you always know the exact value? – christophano Apr 17 '15 at 21:52
  • possible duplicate of [Replace all occurences of a string from a string array](http://stackoverflow.com/questions/11789750/replace-all-occurences-of-a-string-from-a-string-array) – MethodMan Apr 17 '15 at 21:52
  • Try this `m_oEnum.Select(s => s.Equals("abc") ? "abc-test" : s);` – chomba Apr 17 '15 at 21:53
  • by the way you do not need `IEnumerable` just declare `m_oEnum` as var m_oEnum` – MethodMan Apr 17 '15 at 21:54
  • note that @chomba's solution will not change the value stored in the array m_oEnum instead return a new collection with the updated values. – diegohb Apr 17 '15 at 21:54
  • 2
    You can't replace items _in_ an instance of `IEnumerable`. You can replace items in instances of some types of classes that implement that interface (modifying the collection), and you can generate new enumerations in which one or more items are replaced according to some criteria. Please clarify your question so that it is clear what you are trying to do. – Peter Duniho Apr 17 '15 at 21:57

5 Answers5

6
m_oEnum  = m_oEnum.Select(s => s == "abc" ? "abc-test" : s).ToArray();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

If your intent is to update a specific value within an array and you will know the index of the item you intend to update:

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

Otherwise, the other answer will accomplish the same effect..just note that the source array variable will not actually change that way.

diegohb
  • 1,857
  • 2
  • 16
  • 34
  • this does not answer the OP's question.. all you are doing here is changing the value based on a single index..what if there were numerous `abc` stings in various locations..then what..? – MethodMan Apr 17 '15 at 22:13
  • think we're all speculating a bit.. but my interpretation of the question was how to change the value of an item in an array - "replace" a specific item, the OP said... however, if a method takes in a parameter of the item's index - then the code above would accomplish the task. – diegohb Apr 17 '15 at 22:25
  • Fair enough..but what I am saying is what if there are 2 strings located in 2 different index positions..then this would not be a very optimal way of coding.. think more in a dynamic way or what if the positions are not fixed.. sometimes you must think outside the box.. because in the programming world noting is ever static.. in regards to never changing.. things always change in the programming world.. – MethodMan Apr 17 '15 at 22:27
  • I completely agree, i asked the question to the OP: will the index be known. my answer speaks to the question as it is worded, as unlikely as that scenario may be, and suggests the other answer that would be more dynamic if the question was just not worded correctly. thanks for your feedback! – diegohb Apr 17 '15 at 22:42
0

Why not use the extension methods?

Consider the following code:

        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}
  • No code duplicate
  • There is no need to type long linq expressions
  • There is no need for additional usings

The source code:

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);
        }
    }
}

The first two methods have been added to change the objects of reference types in place. Of course, you can use just the third method for all types.

Same answer for another question: https://stackoverflow.com/posts/38728879/edit

Community
  • 1
  • 1
Ruslan L.
  • 436
  • 3
  • 7
-1

To build off of Tim Schmelter's answer you would implement with your existing code like this notice how you do not need to declare the variable as IEnumerable<string>

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

enter image description here

MethodMan
  • 18,625
  • 6
  • 34
  • 52
-3

Try somehing like

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