3

In my program, I have a function that finds the nearest index to an integer.

var indexWinnder = Array.IndexOf(scoreArray, nearestScore)

But the way that Array.IndexOf works is it finds the first match and uses that. I want a random index. Not the first. not the last. Is there any way I can do this?

  • Yes. Write an extension method which does what you want. Then use it. (https://stackoverflow.com/questions/1183083/is-it-possible-to-extend-arrays-in-c) – Ryan Wilson Feb 27 '20 at 18:23
  • Break the problem down. Here's one way to break it down: (1) find the indices of all the matches, (2) pick a random index from the set of indices. Now you have two simpler problems to solve. Can you solve those two problems? Can you show us the code? If those problems are too hard, can you break them down further into simpler problems, until you get to a problem you can solve? – Eric Lippert Feb 27 '20 at 18:27
  • `var randomItem = scoreArray.OrderBy(_ => rand.Next()).First();` where `rand` is a class level variable of new `Random`. Meaning, shuffle the array and get the first item. –  Feb 27 '20 at 19:52

3 Answers3

0

There is no built-in method for that, but you could use your own method instead. My example uses a generic version of possible implementation.

class Program
{
    static void Main(string[] args)
    {
        var arr = new int[] { 1, 2, 3, 1, 1, 5, 2, 6, 1 };

        var randomIndex = RandomIndexOf(arr, 1);

        Console.WriteLine(randomIndex);
        Console.ReadKey();
    }

    static int RandomIndexOf<T>(ICollection<T> arr, T element)
    {
        var indexes = arr.Select((x, i) => new { Element = x, Index = i })
            .Where(x => element.Equals(x.Element))
            .Select(x => x.Index)
            .ToList();

        if (indexes.Count == 0) // there is no matching elements
        {
            return -1;
        }

        var rand = new Random();
        var randomIndex = rand.Next(0, indexes.Count);

        return indexes[randomIndex];
    }
}
Yehor Androsov
  • 4,885
  • 2
  • 23
  • 40
  • 2
    This is a rather complicated answer. A simple answer would be more appropriate and helpful to such basic questions. – Kamran Feb 27 '20 at 19:01
  • Works perfectly and just what I needed for my program. At the moment I am trying to create a class that has useful array methods such as this. Do you consent to me adding this and crediting you? @YegorAndrosov –  Feb 28 '20 at 15:46
  • @isXander no need to credit, there is nothing unique in my answer :) – Yehor Androsov Feb 28 '20 at 16:45
0

Maybe something like this is what you want:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        int[] sampleArray = new int[] { 1, 2, 3, 2, 1, 3, 1, 2, 3 };

        var indices = getAllIndices(sampleArray, i => i == 2);
        var rnd = new Random();
        var i = rnd.Next(0, indices.Count());
        var randomIndex = indices.ElementAt(i);

        Console.WriteLine(randomIndex);
        Console.ReadLine();
    }

    static IEnumerable<int> getAllIndices(int[] array, Predicate<int> predicate)
    {
        for (var i = 0; i < array.Length; i++)
        {
            if (predicate(array[i]))
                yield return i;
        }
    }
}

HTH

Update

Don't forget to check for empty arrays, null arguments etc.

Kamran
  • 782
  • 10
  • 35
  • 1
    for empty array your method won't yield any results, which will lead to rnd.Next(0, 0), so randomIndex will become 0, which is not true – Yehor Androsov Feb 27 '20 at 18:47
  • This is just an example and the edge cases should be taken into account by the programmer. – Kamran Feb 27 '20 at 18:53
-1

I dont know if i understood your problem right but if u just want a random index you could write a method and use:

Random rnd = new Random();
int index = rnd.Next(MinValue, MaxValue); // e.g: MinValue: 0, MaxValue: Length of the Array

and then just use that index as the array index.

Random isnt the best option if u really want a random one because it follows a specific pattern that will occur again and again and again. If u want something even more Random you could look into RNGCryptoServiceProvider: https://www.dotnetperls.com/rngcryptoserviceprovider. Hope this helps!

Niggo
  • 81
  • 1
  • 9
  • I didn't want to find any index, I wanted to find a random index with a value if there is more than one. –  Feb 28 '20 at 16:34
  • oh ok then im sorry, im not a native english speaker, but thanks for clarifying – Niggo Feb 28 '20 at 19:36