তালিকার এলোমেলো আইটেমটি কীভাবে অ্যাক্সেস করবেন?


233

আমার একটি অ্যারেলিস্ট রয়েছে এবং আমার একটি বোতামে ক্লিক করতে সক্ষম হতে হবে এবং তারপরে এলোমেলোভাবে সেই তালিকা থেকে একটি স্ট্রিং বেছে নিয়ে একটি বার্তা বাক্সে প্রদর্শন করতে হবে।

আমি কীভাবে এটি করতে যাব?

উত্তর:


404
  1. Randomকোথাও শ্রেণীর উদাহরণ তৈরি করুন । মনে রাখবেন যে প্রতিবার আপনার এলোমেলো সংখ্যার প্রয়োজন হলে নতুন উদাহরণ তৈরি না করা বেশ গুরুত্বপূর্ণ। উত্পন্ন সংখ্যায় অভিন্নতা অর্জন করতে আপনার পুরানো উদাহরণটি পুনরায় ব্যবহার করা উচিত। আপনার staticকোথাও একটি ক্ষেত্র থাকতে পারে (থ্রেড সুরক্ষা সংক্রান্ত বিষয়ে সতর্ক থাকুন):

    static Random rnd = new Random();
  2. Randomউদাহরণটিতে আপনাকে আইটেমের সর্বাধিক সংখ্যার সাথে একটি এলোমেলো সংখ্যা দেওয়ার জন্য জিজ্ঞাসা করুন ArrayList:

    int r = rnd.Next(list.Count);
  3. স্ট্রিং প্রদর্শিত:

    MessageBox.Show((string)list[r]);

এটি সংশোধন করার কোনও ভাল উপায় আছে যাতে কোনও সংখ্যার পুনরাবৃত্তি না হয়? ধরা যাক যে আমি একবারে এলোমেলোভাবে নির্বাচন করে কার্ডগুলির একটি ডেকে পরিবর্তন করতে চেয়েছিলাম, তবে স্পষ্টতই একই কার্ডটি দুটিবার নির্বাচন করতে পারি না।
AdamMc331

7
@ McAdam331 লুক আপ ফিশার-ইয়েটস এলোমেলো অ্যালগরিদম: en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Mehrdad Afshari

2
উপাদান সর্বাধিক অ্যাক্সেস এড়ানোর জন্য এটি "rnd.Next (list.Count) এর পরিবর্তে" rnd.Next (list.Count-1) "হওয়া উচিত, যা সম্ভবত 0-ভিত্তিক সূচক ছাড়িয়ে যাবে?
বি ক্লে শ্যানন

22
@ বি ক্লেশানন নং। কলটিতে উপরের দিকে Next(max)একচেটিয়া।
মেহরদাদ আফশারি

1
তালিকা খালি হলে কী হবে?
tsu1980

137

আমি সাধারণত এক্সটেনশন পদ্ধতিগুলির এই সামান্য সংগ্রহটি ব্যবহার করি:

public static class EnumerableExtension
{
    public static T PickRandom<T>(this IEnumerable<T> source)
    {
        return source.PickRandom(1).Single();
    }

    public static IEnumerable<T> PickRandom<T>(this IEnumerable<T> source, int count)
    {
        return source.Shuffle().Take(count);
    }

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
    {
        return source.OrderBy(x => Guid.NewGuid());
    }
}

দৃ strongly়ভাবে টাইপ করা তালিকার জন্য, এটি আপনাকে লেখার অনুমতি দেবে:

var strings = new List<string>();
var randomString = strings.PickRandom();

আপনার সমস্ত কিছু যদি অ্যারেলিস্ট হয় তবে আপনি এটি কাস্ট করতে পারেন:

var strings = myArrayList.Cast<string>();

তাদের জটিলতা কি? আইনিম্যারেবলের অলস প্রকৃতির অর্থ কী এটি ও (এন) নয়?
ডেভ হিলিয়ার

17
এই উত্তরটি প্রতিবার আপনি এলোমেলো সংখ্যা বাছাই করার পরে তালিকাকে নতুন করে বদলে দেয়। বিশেষত বড় তালিকাগুলির জন্য এলোমেলো সূচকের মানটি ফিরিয়ে দেওয়া আরও বেশি দক্ষ হবে। পিকর্যান্ডম এ এটি ব্যবহার করুন -return list[rnd.Next(list.Count)];
3:25

এটি মূল তালিকাটি
বদল

.OrderBy (।) অন্য তালিকা তৈরি করে না - এটি IEnumerable <T> প্রকারের একটি অবজেক্ট তৈরি করে যা মূল তালিকার মাধ্যমে আদেশ অনুসারে পুনরাবৃত্তি করে।
জোহান টিডন

5
জিইউইডি প্রজন্মের অ্যালগরিদমটি অনুমানযোগ্য তবে এলোমেলো নয়। Randomপরিবর্তে স্থির অবস্থায় একটি দৃষ্টান্ত রাখা বিবেচনা করুন ।
দাই

90

আপনি করতে পারেন:

list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()

সুন্দর। এএসপি.নেট এমভিসি ৪.৪-তে, একটি তালিকা তৈরি করে আমাকে এটিকে পরিবর্তন করতে হয়েছিল: list.OrderBy (x => Guid.NewGuid ())। ফার্স্টআরডিফল্ট ();
অ্যান্ডি ব্রাউন

3
বেশিরভাগ ক্ষেত্রে এটি বিবেচিত হবে না তবে এটি সম্ভবত rnd.Next ব্যবহারের চেয়ে অনেক ধীর। OTOH এটি কেবলমাত্র তালিকাগুলি নয়, IEnumerable <T> এ কাজ করবে।
দ্রাবনীয় ফিশ

12
নিশ্চিত না যে এটি কতটা এলোমেলো। গাইডগুলি অনন্য, এলোমেলো নয়।
পম্বার

1
আমি মনে করি এই উত্তরটির একটি আরও ভাল এবং বর্ধিত সংস্করণ এবং @ সলিউলফিশের মন্তব্যটি একই উত্তরটিতে সুন্দরভাবে সংক্ষেপে এই উত্তরটিতে ( আমার মন্তব্য ) সংক্ষেপিত হয়েছে ।
নিও

23

একটি Randomউদাহরণ তৈরি করুন :

Random rnd = new Random();

একটি এলোমেলো স্ট্রিং আনুন:

string s = arraylist[rnd.Next(arraylist.Count)];

তবে মনে রাখবেন যে আপনি যদি এটি ঘন ঘন করেন তবে আপনাকে অবশ্যই Randomঅবজেক্টটি পুনরায় ব্যবহার করা উচিত । এটিকে ক্লাসে স্থির ক্ষেত্র হিসাবে রাখুন যাতে এটি একবারেই আরম্ভ করা হয় এবং তারপরে এটি অ্যাক্সেস করে।


20

বা এর মতো সাধারণ এক্সটেনশন ক্লাস:

public static class CollectionExtension
{
    private static Random rng = new Random();

    public static T RandomElement<T>(this IList<T> list)
    {
        return list[rng.Next(list.Count)];
    }

    public static T RandomElement<T>(this T[] array)
    {
        return array[rng.Next(array.Length)];
    }
}

তারপরে কেবল কল করুন:

myList.RandomElement();

অ্যারেগুলির জন্যও কাজ করে।

আমি কল OrderBy()করা এড়াতে চাই কারণ এটি বৃহত্তর সংগ্রহের জন্য ব্যয়বহুল হতে পারে। List<T>এই উদ্দেশ্যে সূচিযুক্ত সংগ্রহগুলি পছন্দ করুন বা অ্যারে ব্যবহার করুন।


3
.NET এ অ্যারে ইতিমধ্যে প্রয়োগ করা হয়েছে IListযাতে দ্বিতীয় ওভারলোড অপ্রয়োজনীয়।
দাই

3

কেন না:

public static T GetRandom<T>(this IEnumerable<T> list)
{
   return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count()));
}

2
ArrayList ar = new ArrayList();
        ar.Add(1);
        ar.Add(5);
        ar.Add(25);
        ar.Add(37);
        ar.Add(6);
        ar.Add(11);
        ar.Add(35);
        Random r = new Random();
        int index = r.Next(0,ar.Count-1);
        MessageBox.Show(ar[index].ToString());

3
যদিও এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না।
gunr2171

3
আমি বলব, maxValueপদ্ধতির প্যারামিটারটি তালিকায় Nextকেবল কয়েকটি সংখ্যক উপাদান হওয়া উচিত, বিয়োগ একটি নয়, কারণ একটি ডকুমেন্টেশন অনুসারে " ম্যাক্সভ্যালু এলোমেলো সংখ্যার একচেটিয়া উপরের সীমানা "।
ডেভিড ফেরেঞ্জি রোগোয়ান

1

আমি এই এক্সটেনশনমেডটিকে কিছুক্ষণ ব্যবহার করছি:

public static IEnumerable<T> GetRandom<T>(this IEnumerable<T> list, int count)
{
    if (count <= 0)
      yield break;
    var r = new Random();
    int limit = (count * 10);
    foreach (var item in list.OrderBy(x => r.Next(0, limit)).Take(count))
      yield return item;
}

আপনি র্যান্ডম ক্লাস উদাহরণটি যুক্ত করতে ভুলে গিয়েছিলেন
বাফসার

1

আমি ভিন্ন পদ্ধতির পরামর্শ দেব, যদি তালিকার অভ্যন্তরের আইটেমগুলির ক্রম নিষ্কাশন করার সময় গুরুত্বপূর্ণ না হয় (এবং প্রতিটি আইটেম কেবল একবারই নির্বাচন করা উচিত), তবে তার পরিবর্তে Listআপনি ConcurrentBagএকটি থ্রেড-নিরাপদ, নিরবচ্ছিন্ন সংগ্রহ যা ব্যবহার করতে পারেন বস্তু:

var bag = new ConcurrentBag<string>();
bag.Add("Foo");
bag.Add("Boo");
bag.Add("Zoo");

ইভেন্ট হ্যান্ডলার:

string result;
if (bag.TryTake(out result))
{
    MessageBox.Show(result);
}

TryTakeUnordered সংগ্রহ থেকে একটি "র্যান্ডম" বস্তু বের করার চেষ্টা করবে।


0

আমার কেবল একটির পরিবর্তে আরও আইটেম দরকার ছিল। সুতরাং, আমি এটি লিখেছি:

public static TList GetSelectedRandom<TList>(this TList list, int count)
       where TList : IList, new()
{
    var r = new Random();
    var rList = new TList();
    while (count > 0 && list.Count > 0)
    {
        var n = r.Next(0, list.Count);
        var e = list[n];
        rList.Add(e);
        list.RemoveAt(n);
        count--;
    }

    return rList;
}

এটির সাহায্যে আপনি এলোমেলোভাবে এর মতো কতগুলি উপাদান চান তা পেতে পারেন:

var _allItems = new List<TModel>()
{
    // ...
    // ...
    // ...
}

var randomItemList = _allItems.GetSelectedRandom(10); 

0

JSON ফাইল থেকে এলোমেলোভাবে দেশের নাম মুদ্রণ করা হচ্ছে।
মডেল:

public class Country
    {
        public string Name { get; set; }
        public string Code { get; set; }
    }

Implementaton:

string filePath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..\")) + @"Data\Country.json";
            string _countryJson = File.ReadAllText(filePath);
            var _country = JsonConvert.DeserializeObject<List<Country>>(_countryJson);


            int index = random.Next(_country.Count);
            Console.WriteLine(_country[index].Name);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.