36

I know c# has Array.FindAll and Array.IndexOf.

Is there a Array.FindAllIndexOf which returns int[]?

bluish
  • 26,356
  • 27
  • 122
  • 180
Eric Yin
  • 8,737
  • 19
  • 77
  • 118

10 Answers10

47
string[] myarr = new string[] {"s", "f", "s"};

int[] v = myarr.Select((b,i) => b == "s" ? i : -1).Where(i => i != -1).ToArray();

This will return 0, 2

If the value does not exist in the array then it will return a int[0].

make an extension method of it

public static class EM
{
    public static int[] FindAllIndexof<T>(this IEnumerable<T> values, T val)
    {
        return values.Select((b,i) => object.Equals(b, val) ? i : -1).Where(i => i != -1).ToArray();
    }
}

and call it like

string[] myarr = new string[] {"s", "f", "s"};

int[] v = myarr.FindAllIndexof("s");
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • 10
    Shorter way - `Enumerable.Range(0, myarr.Length).Where(i => myarr[i] == "s").ToArray();` – diesel Sep 19 '16 at 09:38
  • @NikhilAgrawal How might this be modified to find all indexes of floating point numbers equal (within precision) to a specified val? – gwizardry Jul 18 '17 at 14:54
7

You can write something like :

string[] someItems = { "cat", "dog", "purple elephant", "unicorn" }; 
var selectedItems = someItems.Select((item, index) => new{
    ItemName = item,
    Position = index});

or

var Items = someItems.Select((item, index) => new{
    ItemName = item,
    Position = index}).Where(i => i.ItemName == "purple elephant");

Read : Get the index of a given item using LINQ

Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
5

Searches for an element that matches the conditions defined by the specified predicate, and returns all the zero-based index of the occurrence within the entire System.Array.

public static int[] FindAllIndex<T>(this T[] array, Predicate<T> match)
{
    return array.Select((value, index) => match(value) ? index : -1)
            .Where(index => index != -1).ToArray();
}
Rocket
  • 51
  • 1
  • 1
5

I know this is an old post, but you can try the following,

string[] cars = {"Volvo", "BMW", "Volvo", "Mazda","BMW","BMW"};
var res = Enumerable.Range(0, cars.Length).Where(i => cars[i] == "BMW").ToList();

returns {1,4,5} as a list

Furkan Öztürk
  • 1,178
  • 11
  • 24
2

No, there is not. But you can write your own extension method.

public static int[] FindAllIndexOf<T>(this T[] a, Predicate<T> match)
{
   T[] subArray = Array.FindAll<T>(a, match);
   return (from T item in subArray select Array.IndexOf(a, item)).ToArray();
}

and then, for your array, call it.

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
stukselbax
  • 5,855
  • 3
  • 32
  • 54
1

You can loop with findIndex giving an index

string[] arr = { "abc", "asd", "def", "abc", "lmn", "wer" };
int index = -1;
do
{
    index = Array.IndexOf(arr, "abc", index + 1);
    System.Console.WriteLine(index);
} while (-1 != index);
msam
  • 4,259
  • 3
  • 19
  • 32
0

I've used Nikhil Agrawal's answer to create the following related method, which may be useful.

public static List<int> FindAllIndexOf<T>(List<T> values, List<T> matches)
    {
        // Initialize list
        List<int> index = new List<int>();

        // For each value in matches get the index and add to the list with indexes
        foreach (var match in matches)
        {
            // Find matches 
            index.AddRange(values.Select((b, i) => Equals(b, match) ? i : -1).Where(i => i != -1).ToList());

        }

        return index;
    }

Which takes a list with values and a list with values that are to be matched. It returns a list of integers with the index of the matches.

0

You can solve this problem by creating only 2 integer variables. More power to you!

string[] seasons= { "Fall","Spring", "Summer", "Fall", "Fall", "Winter"};

int i = 0;

int IndexOfFallInArray = 0;

int[] IndexesOfFall= new int[seasons.Length];

foreach (var item in seasons)
{
    if (item == "Fall")
        {
            IndexesOfFall[i] = IndexOfFallInArray;
            i++;
        }
        IndexOfFallInArray++;
}
0

How about simply:

public static IEnumerable<int> Available()
    {
        for (int i = 0; i < myarr.Length; i++)
        {
            if (myarr[i] is null) //Your predicate here...
                yield return i;
        }
    }
Jawid Hassim
  • 357
  • 3
  • 9
-1

I'm aware that the question is answered already, this is just another way of doing it. note that I used ArrayList instead of int[]

// required using directives
using System;
using System.Collections;

String      inputString = "The lazy fox couldn't jump, poor fox!";
ArrayList   locations   =  new ArrayList();      // array for found indexes
string[] lineArray = inputString.Split(' ');     // inputString to array of strings separated by spaces

int tempInt = 0;
foreach (string element in lineArray)
{
     if (element == "fox")
     {
         locations.Add(tempInt);   // tempInt will be the index of current found index and added to Arraylist for further processing 
     }
 tempInt++;
}