সি # তে সংগ্রহগুলি ফিল্টার করছে


142

আমি সি # তে একটি সংগ্রহ ফিল্টার করার জন্য খুব দ্রুত উপায় খুঁজছি। আমি বর্তমানে জেনেরিক তালিকা <অবজেক্ট> সংগ্রহগুলি ব্যবহার করছি তবে অন্যান্য স্ট্রাকচারগুলি যদি তারা আরও ভাল সম্পাদন করে তবে তাদের ব্যবহারের জন্য আমি উন্মুক্ত।

বর্তমানে, আমি কেবলমাত্র একটি নতুন তালিকা তৈরি করছি <অবজেক্ট> এবং মূল তালিকাটি থেকে লুপিং। যদি ফিল্টারিংয়ের মানদণ্ড মেলে তবে আমি একটি অনুলিপি নতুন তালিকায় রেখেছি।

এই কাজ করতে একটি ভাল উপায় আছে কি? অস্থায়ী তালিকা প্রয়োজন নেই তাই জায়গায় ফিল্টার করার কোনও উপায় আছে?


এটি নির্লজ্জভাবে দ্রুত হতে চলেছে। এটি কি আপনার সিস্টেমকে ধীর করে দিচ্ছে? একটি বিশাল তালিকা হয়? নাহলে আমি চিন্তা করতাম না।
আইয়েন ধারক

উত্তর:


237

আপনি যদি সি # 3.0 ব্যবহার করেন তবে আপনি লিনক ব্যবহার করতে পারেন, আরও ভাল এবং আরও মার্জিত উপায়:

List<int> myList = GetListOfIntsFromSomewhere();

// This will filter out the list of ints that are > than 7, Where returns an
// IEnumerable<T> so a call to ToList is required to convert back to a List<T>.
List<int> filteredList = myList.Where( x => x > 7).ToList();

যদি আপনি এটি না খুঁজে পান তবে এর .Whereঅর্থ using System.Linq;আপনার ফাইলের শীর্ষে আমদানি করা দরকার ।


19
দ্য এক্সটেনশন পদ্ধতিটি অনুমানযোগ্য <T>, তালিকা <টি> নয় returns এটি হওয়া উচিত: myList.Where (x => x> 7) .ToList ()
রাফা

1
স্ট্রিং দ্বারা ফিল্টারিংয়ের জন্য এটি কীভাবে কাজ করে। "Ch" দিয়ে শুরু হওয়া স্ট্রিংগুলির তালিকার সমস্ত আইটেম সন্ধান করার মতো
joncodo

2
@ জোনাথনো আপনি ফানকের অভ্যন্তরীণ পদ্ধতিগুলি ব্যবহার করতে পারেন। listOfStrings.Where (s => s.SarttsWith ("ch"))। ToList ();
মাইক জি

1
লিনাকের প্রশ্নগুলিকে আপত্তি জানানোর কোনও উপায় আছে কি? উদাহরণস্বরূপ, ব্যবহারের .Where(predefinedQuery)পরিবর্তে ব্যবহার করার জন্য .Where(x => x > 7)?
জেনোরো

2
@ অ্যালমিটিআর: কেবল এটিকে একটি পদ্ধতি হিসাবে ব্যাখ্যা করুন যা একটি যুক্তি গ্রহণ করে। উদা: public bool predefinedQuery(int x) { return x > 7; }। তাহলে আপনার ভাল .Where(predefinedQuery)কাজ করবে।
ডন

21

লাম্বডাস এবং লিনকু ভিত্তিক তালিকা ফিল্টারিং দেখানোর জন্য আমি তিনটি পৃথক পদ্ধতি ব্যবহার করে কিছু তালিকা ফিল্টারিংয়ের একটি কোড ব্লক / উদাহরণ এখানে দেব।

#region List Filtering

static void Main(string[] args)
{
    ListFiltering();
    Console.ReadLine();
}

private static void ListFiltering()
{
    var PersonList = new List<Person>();

    PersonList.Add(new Person() { Age = 23, Name = "Jon", Gender = "M" }); //Non-Constructor Object Property Initialization
    PersonList.Add(new Person() { Age = 24, Name = "Jack", Gender = "M" });
    PersonList.Add(new Person() { Age = 29, Name = "Billy", Gender = "M" });

    PersonList.Add(new Person() { Age = 33, Name = "Bob", Gender = "M" });
    PersonList.Add(new Person() { Age = 45, Name = "Frank", Gender = "M" });

    PersonList.Add(new Person() { Age = 24, Name = "Anna", Gender = "F" });
    PersonList.Add(new Person() { Age = 29, Name = "Sue", Gender = "F" });
    PersonList.Add(new Person() { Age = 35, Name = "Sally", Gender = "F" });
    PersonList.Add(new Person() { Age = 36, Name = "Jane", Gender = "F" });
    PersonList.Add(new Person() { Age = 42, Name = "Jill", Gender = "F" });

    //Logic: Show me all males that are less than 30 years old.

    Console.WriteLine("");
    //Iterative Method
    Console.WriteLine("List Filter Normal Way:");
    foreach (var p in PersonList)
        if (p.Gender == "M" && p.Age < 30)
            Console.WriteLine(p.Name + " is " + p.Age);

    Console.WriteLine("");
    //Lambda Filter Method
    Console.WriteLine("List Filter Lambda Way");
    foreach (var p in PersonList.Where(p => (p.Gender == "M" && p.Age < 30))) //.Where is an extension method
        Console.WriteLine(p.Name + " is " + p.Age);

    Console.WriteLine("");
    //LINQ Query Method
    Console.WriteLine("List Filter LINQ Way:");
    foreach (var v in from p in PersonList
                      where p.Gender == "M" && p.Age < 30
                      select new { p.Name, p.Age })
        Console.WriteLine(v.Name + " is " + v.Age);
}

private class Person
{
    public Person() { }
    public int Age { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
}

#endregion

14

List<T> একটি আছে FindAll পদ্ধতি রয়েছে যা আপনার জন্য ফিল্টারিং করবে এবং তালিকার একটি সাবসেট ফিরিয়ে দেবে।

এমএসডিএন-এর একটি দুর্দান্ত কোড উদাহরণ রয়েছে: http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx

সম্পাদনা: আমি লিনকিউ এবং Where()পদ্ধতি সম্পর্কে ভাল ধারণা পাওয়ার আগে এটি লিখেছিলাম । আমি যদি আজ এটি লিখতে চাই তবে আমি সম্ভবত জর্জের উপরে বর্ণিত পদ্ধতিটি ব্যবহার করব। FindAllপদ্ধতি এখনো কাজ করে যদি আপনি একটি .NET 2.0 পরিবেশ যদিও আটকে আছেন।


4
লিনক ঠিক আছে, তবে কমপক্ষে এক মাত্রা ধীর গতির, সুতরাং ফাইন্ডআল এবং ফিল্টারিং এক্সটেনশন পদ্ধতিগুলি (উদাহরণস্বরূপ অ্যারেগুলির মধ্যে একটি গুচ্ছ রয়েছে) যা কর্মক্ষেত্রের ক্ষেত্রে গুরুত্বপূর্ণ পরিস্থিতিতে দৃশ্যের জন্য নির্ভরযোগ্য নয়। (এফডাব্লুআইডাব্লু, আমি লিনক এবং / অথবা আইউনামেবল, সাধারণত সাধারণত ফ্যাক্টর 7 থেকে 50 এর বেশি সময় পর্যন্ত ফলাফল পেয়েছি)
ফিল্ম

এটি গ্রহণযোগ্য উত্তর না হওয়ার কোনও কারণ আছে কি? এটি মনে হচ্ছে এটি দ্রুততর এবং সিনট্যাক্সটি আরও পরিষ্কার (শেষে কোনও লিস্ট () নেই call
রান লোটোমে

6

একটি অস্থায়ী তালিকার প্রয়োজনীয়তা অপসারণ করতে আপনি IEnumerable ব্যবহার করতে পারেন।

public IEnumerable<T> GetFilteredItems(IEnumerable<T> collection)
{
    foreach (T item in collection)
    if (Matches<T>(item))
    {
        yield return item;
    }
}

ম্যাচগুলি যেখানে আপনার ফিল্টার পদ্ধতির নাম। এবং আপনি এটি ব্যবহার করতে পারেন:

IEnumerable<MyType> filteredItems = GetFilteredItems(myList);
foreach (MyType item in filteredItems)
{
    // do sth with your filtered items
}

এটি যখন প্রয়োজন হবে তখন getFilteredItems ফাংশন কল করবে এবং কিছু ক্ষেত্রে আপনি ফিল্টারকৃত সংগ্রহে সমস্ত আইটেম ব্যবহার করবেন না, এটি কিছু ভাল পারফরম্যান্স লাভ প্রদান করতে পারে।


4

এটি জায়গায় করার জন্য, আপনি একটি কাস্টম "প্রেডিকেট" শ্রেণীর পাশাপাশি "তালিকা <>" শ্রেণীর সরান সমস্ত পদ্ধতি ব্যবহার করতে পারেন ... তবে যা কিছুই কোড পরিষ্কার করে ... হুডের নীচে এটি একই করছে doing জিনিস আপনি যা ... তবে হ্যাঁ, এটি এটি জায়গায় করে তোলে, তাই আপনি টেম্প তালিকার একই কাজ।


4

আপনি তালিকার FindAll পদ্ধতিটি ব্যবহার করতে পারেন , ফিল্টার করার জন্য একটি প্রতিনিধি সরবরাহ করে। যদিও আমি @ আইইএনএমএইচ-এর সাথে একমত যে এটি একটি বিশাল তালিকা না থাকলে নিজেকে খুব বেশি চিন্তিত করা উচিত নয়।


3

আপনি যদি সি # 3.0 ব্যবহার করেন তবে আপনি লিনক ব্যবহার করতে পারেন

অথবা, আপনি যদি পছন্দ করেন তবে সি # 3 সংকলক দ্বারা সরবরাহ করা বিশেষ কোয়েরি সিনট্যাক্সটি ব্যবহার করুন:

var filteredList = from x in myList
                   where x > 7
                   select x;

3

তালিকা FindAllপদ্ধতিতে সরবরাহ করা প্রিডিকেট ব্যবহারের তুলনায় লিনকিউ ব্যবহার করা তুলনামূলকভাবে ধীর । লিনকিউ সম্পর্কেও সতর্ক থাকুন কারণ listআপনি ফলটি অ্যাক্সেস না করা পর্যন্ত এর গণনাটি আসলে কার্যকর করা হয় না। এর অর্থ এই হতে পারে যে, আপনি যখন মনে করেন যে আপনি একটি ফিল্টারড তালিকা তৈরি করেছেন, তখন সামগ্রীটি আপনি যখন পড়বেন তখন আপনি যা প্রত্যাশা করেছিলেন তার থেকে আলাদা হতে পারে।


1

যদি আপনার তালিকাটি খুব বড় এবং আপনি বারবার ফিল্টার করছেন - আপনি শুরু এবং শেষের পয়েন্টগুলি সন্ধান করতে বাইনারি অনুসন্ধানের জন্য ফিল্টার বৈশিষ্ট্যে মূল তালিকাটি বাছাই করতে পারেন sort

প্রাথমিক সময় ও (এন * লগ (এন)) এর পরে ও (লগ (এন))।

স্ট্যান্ডার্ড ফিল্টারিং প্রতিটি সময় ও (এন) নেবে।

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