简体   繁体   中英

getting the index of an array, multiple times, then storing them in an array c#

I want to get the index of an array which I have done with Array.IndexOf(array, value) . This works good with one value but I want to get every occurrence of the value and store the index's into another array. For example, the name 'tom' appears 5 times in an array, I want to find the index positions of each one.

Maybe something like this? This uses a list rather than an array, but it follows the same idea.

List<int> Indexes = new List<int>();

for (int i = 0; i < array.Count(); i++)
{
    if (array[i] == "tom")
    {
        Indexes.Add(i);
    }
}

This solution is like the previous one, but will run faster:

string value = "tom";
int[] indices = stringArray.Where(s => s != null)
                           .Select((s, i) => s.Equals(value) ? i: -1)
                           .Where(i => i >= 0)
                           .ToArray();

If I'm not mistaken, you can add another parameter to IndexOf() , which will let you specify where in the array to start. This should give you more or less what you need:

var indices = new List<int>();
int i = Array.IndexOf(array, val);
while(i > -1){
    indices.Add(i);
    i = Array.IndexOf(array, val, i+1);
} 

// ... and if it is important to have the result as an array:
int[] result = indices.ToArray();

Practical example:

var array = new int[]{ 1, 2, 3, 3, 4, 5, 3, 6, 7, 8, 3};
int val = 3;

var indices = new List<int>();    
int i = Array.IndexOf(array, val);
while(i > -1){
    indices.Add(i);
    i = Array.IndexOf(array, val, i+1);
}

// ... and if it is important to have the result as an array:
int[] result = indices.ToArray();

Edit: Just realized a while-loop may well be a lot cleaner than a for-loop for this.


Edit 2: Due to popular demand (see comment below), here`s the original beautiful non-basic for-loop, re-introduced just for your reading pleasure:

for(int i = Array.IndexOf(array, val); i > -1; i = Array.IndexOf(array, val, i+1)){
    indices.Add(i);        
} 

Could create an extension method to do it

namespace Extensions
{
    public static class ArrayExtension
    {
        public static IEnumerable<int> GetIndicesOf<T>(this T[] target, T val, int start = 0)
        {
            EqualityComparer<T> comparer = EqualityComparer<T>.Default;
            for (int i = start; i < target.Length; i++)
            {
                if (comparer.Equals(target[i], val))
                {
                    yield return i;
                }
            }
        }
    }
}

Add the using statement for your namespace with the extension method using Extensions; in the file you want to call it in.

Then to call it just do the following to get the indices.

IEnumerable<int> indices = array.GetIndicesOf(value);

or to get an array just do

int[] indicies = array.GetIndicesOf(value).ToArray();

You can use LINQ's Select overload which uses elements index as well, like:

var indices = stringArray.Select((s, i) => new {Value = s, Index = i})
    .Where(r => r.Value == "tom")
    .Select(r => r.Index);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM