c# - একটি বিশেষ সম্পত্তি নেভিগেশন LINQ এর Distinct()




.net-3.5 (13)

আমি যদি এক বা একাধিক সম্পত্তি উপর ভিত্তি করে একটি স্বতন্ত্র তালিকা পেতে চান?

সরল! আপনি তাদের গ্রুপ করতে চান এবং দলের বাইরে একটি বিজয়ী বাছাই করতে চান।

List<Person> distinctPeople = allPeople
  .GroupBy(p => p.PersonId)
  .Select(g => g.First())
  .ToList();

আপনি যদি একাধিক বৈশিষ্ট্যের গোষ্ঠী সংজ্ঞায়িত করতে চান তবে এখানে কীভাবে:

List<Person> distinctPeople = allPeople
  .GroupBy(p => new {p.PersonId, p.FavoriteColor} )
  .Select(g => g.First())
  .ToList();

আমি LINQ এর সাথে এটি সম্পর্কে খেলতে খেলছি, কিন্তু ডিফিন্টিক ব্যবহার করার সময় আমি কীভাবে সাধারণ তালিকাটি ব্যবহার করতে পারি না (পূর্ণসংখ্যার একটি সাধারণ তালিকাটি করা খুবই সহজ, এটি কোন প্রশ্ন নয়)। যদি আমি ব্যবহার করতে চাই তবে বস্তুর এক বা একাধিক বৈশিষ্ট্যের উপর একটি বস্তুর একটি তালিকাতে Distinct ?

উদাহরণ: সম্পত্তি Id সহ কোনও বস্তু Person । আমি কিভাবে সমস্ত ব্যক্তি পেতে পারি এবং বস্তুর সম্পত্তি Id দিয়ে তাদের উপর ভিন্ন ব্যবহার করতে পারি?

Person1: Id=1, Name="Test1"
Person2: Id=1, Name="Test1"
Person3: Id=2, Name="Test2"

আমি কিভাবে Person1 এবং Person3 পেতে পারেন? এটা কি সম্ভব?

LINQ এর সাথে যদি এটি সম্ভব না হয়, তবে নেটের 3.5 টি বৈশিষ্ট্যের উপর নির্ভর করে Person তালিকা থাকা সর্বোত্তম উপায় কী হবে?


আপনার ক্ষেত্র দ্বারা সমাধান প্রথম গ্রুপ তারপর firstordefault আইটেম নির্বাচন করুন।

    List<Person> distinctPeople = allPeople
   .GroupBy(p => p.PersonId)
   .Select(g => g.FirstOrDefault())
   .ToList();

আপনি Person.id উপর আসলে সমান করতে ব্যক্তির উপর সমান ওভাররাইড করতে সক্ষম হওয়া উচিত। এই আপনি পরে করছি আচরণ ফলাফল করা উচিত।


আপনি standard Linq.ToLookup() সাথে এটি করতে পারেন। এটি প্রতিটি অনন্য কীয়ের জন্য মানগুলির একটি সংগ্রহ তৈরি করবে। শুধু সংগ্রহে প্রথম আইটেম নির্বাচন করুন

Persons.ToLookup(p => p.Id).Select(coll => coll.First());

আমি এটা যথেষ্ট মনে হয়:

list.Select(s => s.MyField).Distinct();

এটি করার সর্বোত্তম উপায় অন্যান্য .NET সংস্করণগুলির সাথে সামঞ্জস্যপূর্ণ। এটি হ্যান্ডেল করতে সমান এবং GetHash ওভাররাইড করা (স্ট্যাক ওভারফ্লো প্রশ্নটি দেখুন এই কোডটি স্বতন্ত্র মান দেয়। তবে, আমি যা চাই তা হল দৃঢ়ভাবে টাইপ করা সংগ্রহটি একটি বেনামী টাইপ ), কিন্তু আপনার কোড জুড়ে জেনারিক যা কিছু প্রয়োজন হলে, এই নিবন্ধটি সমাধান মহান।


নিচের কোড দিয়ে চেষ্টা করুন।

var Item = GetAll().GroupBy(x => x .Id).ToList();

নিম্নলিখিত কোডটি কার্যকরীভাবে জন স্কিটের উত্তরের সমতুল্য।

.NET 4.5 এ পরীক্ষা করা, LINQ এর পূর্ববর্তী সংস্করণে কাজ করা উচিত।

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
  this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
  HashSet<TKey> seenKeys = new HashSet<TKey>();
  return source.Where(element => seenKeys.Add(keySelector(element)));
}

গুপ্তচর, code.google.com/p/morelinq/source/browse/MoreLinq/DistinctBy.cs


ব্যক্তিগতভাবে আমি নিম্নোক্ত ক্লাস ব্যবহার করি:

public class LambdaEqualityComparer<TSource, TDest> : 
    IEqualityComparer<TSource>
{
    private Func<TSource, TDest> _selector;

    public LambdaEqualityComparer(Func<TSource, TDest> selector)
    {
        _selector = selector;
    }

    public bool Equals(TSource obj, TSource other)
    {
        return _selector(obj).Equals(_selector(other));
    }

    public int GetHashCode(TSource obj)
    {
        return _selector(obj).GetHashCode();
    }
}

তারপর, একটি এক্সটেনশান পদ্ধতি:

public static IEnumerable<TSource> Distinct<TSource, TCompare>(
    this IEnumerable<TSource> source, Func<TSource, TCompare> selector)
{
    return source.Distinct(new LambdaEqualityComparer<TSource, TCompare>(selector));
}

অবশেষে, উদ্দেশ্যে ব্যবহার:

var dates = new List<DateTime>() { /* ... */ }
var distinctYears = dates.Distinct(date => date.Year);

এই পদ্ধতিটি ব্যবহার করে আমি যে সুবিধাটি লাভ করেছি তা হল LambdaEqualityComparer ক্লাসের LambdaEqualityComparer যা অন্য পদ্ধতিগুলির জন্য একটি IEqualityComparer স্বীকার করে। (ওহ, এবং আমি মূল LINQ বাস্তবায়ন yield উপাদান ছেড়ে ...)


ব্যবহার করুন:

List<Person> pList = new List<Person>();
/* Fill list */

var result = pList.Where(p => p.Name != null).GroupBy(p => p.Id).Select(grp => grp.FirstOrDefault());

where আপনি এন্ট্রি ফিল্টার করতে সাহায্য করে (আরো জটিল হতে পারে) এবং groupby এবং স্বতন্ত্র ফাংশন সঞ্চালন select


যদি আপনার একাধিক বৈশিষ্ট্যের একটি পৃথক পদ্ধতি প্রয়োজন হয়, তবে আপনি আমার PowerfulExtensions লাইব্রেরীটি পরীক্ষা করতে পারেন। বর্তমানে এটি খুব অল্প বয়সে রয়েছে, তবে ইতিমধ্যে আপনি ডিস্ট্রিক্ট, ইউনিয়ন, ইন্টেরেক্ট মত পদ্ধতি ব্যবহার করতে পারেন, কোনও সংখ্যার ব্যতীত;

আপনি এটি কিভাবে ব্যবহার করেন:

using PowerfulExtensions.Linq;
...
var distinct = myArray.Distinct(x => x.A, x => x.B);

যদি আপনি LINQ- এর মতো দেখতে চান তবে আপনি কোয়েরি সিনট্যাক্স ব্যবহার করতে পারেন:

var uniquePeople = from p in people
                   group p by new {p.ID} //or group by new {p.ID, p.Name, p.Whatever}
                   into mygroup
                   select mygroup.FirstOrDefault();

List<Person>lst=new List<Person>
        var result1 = lst.OrderByDescending(a => a.ID).Select(a =>new Player {ID=a.ID,Name=a.Name} ).Distinct();






distinct