在数组中查找一个值的随机索引

3
在我的程序中,我有一个函数用于找到最接近整数的索引。
var indexWinnder = Array.IndexOf(scoreArray, nearestScore)

Array.IndexOf 的工作方式是查找第一个匹配项并使用它。我想要一个随机的索引,而不是第一个或最后一个。有没有办法做到这一点?


是的。编写一个扩展方法来实现你想要的功能,然后使用它。(https://dev59.com/GXM_5IYBdhLWcg3w4njb) - Ryan Wilson
把问题分解开来。以下是一种分解方法:(1)找到所有匹配项的索引,(2)从索引集合中随机选择一个索引。现在你有两个更简单的问题要解决。你能解决这两个问题吗?你能展示一下代码吗?如果这些问题太难了,你能进一步将它们分解成更简单的问题,直到你遇到一个你能解决的问题吗? - Eric Lippert
var randomItem = scoreArray.OrderBy(_ => rand.Next()).First(); 的意思是,将 scoreArray 数组随机排序,然后取第一个元素。其中,rand 是一个新的 Random 类级别变量。 - user10216583
3个回答

0

没有内置的方法可以实现这个功能,但是你可以使用自己的方法来代替。我的示例使用了一个通用版本的可能实现。

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

2
这是一个相当复杂的答案。对于这样基础的问题,提供简单明了的答案会更加合适和有帮助。 - Kamran
完美地运作,正是我程序所需要的。目前我正在尝试创建一个类,其中包含有用的数组方法,例如这个。您是否同意我添加并给予您信誉?@YegorAndrosov - user12974941
@isXander 不用提及,我的回答没有什么独特的地方 :) - Yehor Androsov

0
也许像这样的东西是你想要的:
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

更新

不要忘记检查空数组、空参数等。


1
对于空数组,你的方法不会产生任何结果,这将导致 rnd.Next(0,0),因此 randomIndex 将变为 0,这是不正确的。 - Yehor Androsov
这只是一个例子,程序员应考虑边缘情况。 - Kamran

-1

我不确定我是否正确地理解了你的问题,但如果你只是想要一个随机索引,你可以编写一个方法并使用:

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

然后只需将该索引用作数组索引。

如果你真的想要一个随机的选项,那么随机数并不是最好的选择,因为它遵循一个特定的模式,会一次又一次地重复出现。如果你想要更加随机的东西,可以考虑使用RNGCryptoServiceProvider:https://www.dotnetperls.com/rngcryptoserviceprovider。希望这能帮到你!


我不想找到任何索引,我想在有多个值的情况下找到一个随机索引。 - user12974941
哦,好的,那我很抱歉,我不是母语为英语的人,但是感谢您澄清。 - Niggo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接