লিনক ব্যবহার করে তালিকায় সদৃশগুলি সরান


313

আমি ক্লাস আছে Itemsসঙ্গে properties (Id, Name, Code, Price)

তালিকাটি Itemsসদৃশ আইটেমগুলির সাথে পপুলেটেড।

প্রাক্তন জন্য .:

1         Item1       IT00001        $100
2         Item2       IT00002        $200
3         Item3       IT00003        $150
1         Item1       IT00001        $100
3         Item3       IT00003        $150

লিনক ব্যবহার করে তালিকার নকলগুলি কীভাবে সরিয়ে ফেলবেন?


আইটেম ক্লাসেও সম্পত্তি হিসাবে আমার আরও একটি ক্লাস রয়েছে
প্রসাদ

আপনি করতে পারেন var set = new HashSet<int>(); var uniques = items.Where(x => set.Add(x.Id));। এটি করা অপরাধী হওয়া উচিত ..
নওফাল

উত্তর:


394
var distinctItems = items.Distinct();

শুধুমাত্র কয়েকটি বৈশিষ্ট্যের সাথে মিল রাখতে, একটি কাস্টম সমতা তুলনামূলক তৈরি করুন, যেমন:

class DistinctItemComparer : IEqualityComparer<Item> {

    public bool Equals(Item x, Item y) {
        return x.Id == y.Id &&
            x.Name == y.Name &&
            x.Code == y.Code &&
            x.Price == y.Price;
    }

    public int GetHashCode(Item obj) {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode() ^
            obj.Code.GetHashCode() ^
            obj.Price.GetHashCode();
    }
}

তারপরে এটি ব্যবহার করুন:

var distinctItems = items.Distinct(new DistinctItemComparer());

হাই ক্রিশ্চান, আমার কাছে <my_Custom_Class> এবং তালিকা <স্ট্রিং> তালিকা থাকলে কোডে কী পরিবর্তন হবে। আমার কাস্টম শ্রেণিতে বিভিন্ন আইটেম রয়েছে যার একটি হ'ল ডিসিএন নম্বর এবং তালিকার <স্ট্রিং> -এ কেবল ডিসিএন নম্বর রয়েছে। সুতরাং আমাকে তালিকাটি পরীক্ষা করতে হবে <কাস্টম_ক্লাস> তালিকায় <স্ট্রিং> থেকে যে কোনও ডিসিএন রয়েছে। উদাহরণস্বরূপ ধরুন তালিকা 1 = তালিকা <কাস্টম_ক্লাস> এবং তালিকা 2 = তালিকা <স্ট্রিং>। যদি তালিকা 1 এর 2000 টি আইটেম থাকে এবং তালিকা 2 এর 40000 আইটেম থাকে যার উপরে তালিকা 1 থেকে 600 আইটেম তালিকাতে উপস্থিত থাকে। সুতরাং এই ক্ষেত্রে আমার তালিকা হিসাবে তালিকা হিসাবে আমার আউটপুট তালিকা হিসাবে 1400 প্রয়োজন। তাহলে কি এক্সপ্রেশন হবে। অগ্রিম ধন্যবাদ

এছাড়াও আরও একটি কেস এখানে রয়েছে যেহেতু তালিকা 1-এ বিভিন্ন আইটেম রয়েছে, অন্য আইটেমের মানগুলি পৃথক হতে পারে তবে ডিসিএন অবশ্যই একই হবে। সুতরাং আমার ক্ষেত্রে ডিসট্রিন্ট কাঙ্ক্ষিত আউটপুট দিতে ব্যর্থ হয়েছিল।

2
আমি তুলনামূলক ক্লাসকে অত্যন্ত দরকারী বলে মনে করি। তারা সাধারণ সম্পত্তির নামের তুলনা ছাড়া অন্য যুক্তি প্রকাশ করতে পারে। আমি গত মাসে একটি নতুন লিখেছিলাম, এমন কিছু করার জন্য যা GroupByকরতে পারেনি।
ক্রিশ্চান হেইটার

ভাল কাজ করে এবং আমাকে নতুন কিছু শিখতে এবং সি # তে XoRঅপারেটরের তদন্ত করতে পেয়েছে ^। ভিবি.এনইটি এর মাধ্যমে ব্যবহার করেছেন তবে Xorএটি প্রথমে কী ছিল তা দেখার জন্য আপনার কোডটিতে একটি দ্বিগুণ গ্রহণ করতে হয়েছিল।
এটকনওয়ে

আমি যখন পৃথক তুলনাকারীকে ব্যবহার করার চেষ্টা করি তখন আমি এই ত্রুটিটি পেয়েছি: "সত্তা থেকে লাইনকিউ পদ্ধতিটি 'সিস্টেম.লিঙ্ক.আইকিউয়েরেবল 1[DataAccess.HR.Dao.CCS_LOCATION_TBL] Distinct[CCS_LOCATION_TBL](System.Linq.IQueryable1 [ডেটাএ্যাক্সেস.এইচ.আর.ডাও.সিসি_লোকেশন_বিবিএল], সিস্টেম.কলেশনস.জেনারিক.আই.কোয়ালিটি কম্পেয়ারে 1 [[ ডেটাএ্যাক্সেস.এইচআর.ডাও.সিসি_সিলকেশন_বিএল]) পদ্ধতি এবং এই পদ্ধতিটি কোনও স্টোর এক্সপ্রেশন হিসাবে অনুবাদ করা যায় না
ব্যবহারকারী 8128167

600
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());

28
ধন্যবাদ - একটি তুলনামূলক ক্লাস লেখা এড়াতে চেয়েছিলেন তাই আমি এই কাজটি করে আনন্দিত :)
জেন

8
+1 এই সমাধান এমনকি টাই-ব্রেকারকেও মঞ্জুরি দেয়: মানদণ্ডের সাথে সদৃশগুলি মুছে ফেলুন!
অ্যাড্রিয়ানো কার্নেরিও

4
তবে একটু ওভারহেড!
আমিরহোসেইন মেহরভারজি

1
তবে, ভিক্টর জুরি যেমন নীচে পরামর্শ দিয়েছেন: ফার্স্টোরডফল্ট ব্যবহার করুন। বিশ্বাস করা যায় না, সেই সমাধানটি এত সহজ হতে পারে (কাস্টম সমতা তুলনামূলক ছাড়াই)
সাইবারহক

6
আপনি একাধিক বৈশিষ্ট্য নিয়ে গ্রুপ করতে পারেন: <XYZ> MyUniqueList = MyList.GroupBy (x => new {x. column1, x. Column2})। নির্বাচন করুন (g => g.First ()) ToList ();
সুমিত জোশী

40

যদি এমন কিছু থাকে যা আপনার ডিসট্রিন্ট কোয়েরিটি ফেলে দিচ্ছে , আপনি মোরলিনাকের দিকে তাকিয়ে ডিস্টিনটবাই অপারেটরটি ব্যবহার করতে এবং আইডির মাধ্যমে পৃথক বস্তু নির্বাচন করতে চাইতে পারেন ।

var distinct = items.DistinctBy( i => i.Id );

1
লিনকের সাথে কোনও ডিস্টিনটবি () পদ্ধতি নেই।
ফ্রেইডুন বারিকজেহী

7
@ ফরিদুন বারিকজেহী তবে তিনি খাঁটি লিনকের কথা বলছেন না। পোস্টে MoreLinq প্রকল্পে linq হচ্ছে ...
Ademar

30

আমি লিনকের সাথে এভাবেই গ্রুপ করতে পেরেছিলাম। আশা করি এটা সাহায্য করবে.

var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());

3
@ নওফাল, আমি ফার্স্ট () এর পরিবর্তে ফার্স্ট ওআরডিফল্ট () -কে পরামর্শ দিচ্ছিলাম
সোমবারিটো

23
আমি যদি সঠিক হয়ে থাকি FirstOrDefaultতবে সাথে Selectসাথে এখানে ব্যবহার করা কোনও লাভ দেয় না GroupBy, কারণ খালি গোষ্ঠী হওয়ার কোনও সম্ভাবনা নেই (গোষ্ঠীগুলি কেবলমাত্র সংগ্রহের বিষয়বস্তু থেকে উদ্ভূত হয়েছিল)
রায় টিঙ্কার

17

ব্যবহার করুন Distinct()তবে মনে রাখবেন যে এটি মানগুলির তুলনা করতে ডিফল্ট সমতা তুলনামূলক ব্যবহার করে, সুতরাং আপনি যদি এর বাইরে কিছু চান তবে আপনার নিজের তুলনামূলক প্রয়োগ করতে হবে।

উদাহরণের জন্য দয়া করে http://msdn.microsoft.com/en-us/library/bb348436.aspx দেখুন ।


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

16

আপনার তালিকায় সদৃশ আইটেম সরানোর জন্য আপনার কাছে এখানে তিনটি বিকল্প রয়েছে:

  1. আ কাস্টম সমতা তুলনামূলক ব্যবহার করুন এবং তারপরে @ ক্রিশ্চিয়ান হাইটার উল্লিখিত Distinct(new DistinctItemComparer())হিসাবে ব্যবহার করুন
  2. ব্যবহার করুন GroupBy, তবে দয়া করে মনে রাখবেন GroupByআপনার সমস্ত কলামগুলিতে গ্রুপ করা উচিত কারণ আপনি যদি Idএটির দ্বারা গোষ্ঠী করেন তবে সদৃশ আইটেমগুলি সদৃশ হয় না। উদাহরণস্বরূপ নিম্নলিখিত উদাহরণটি বিবেচনা করুন:

    List<Item> a = new List<Item>
    {
        new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
        new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200},
        new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
        new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
        new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
        new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
    };
    var distinctItems = a.GroupBy(x => x.Id).Select(y => y.First());

    এই গ্রুপিংয়ের ফলাফলটি হবে:

    {Id = 1, Name = "Item1", Code = "IT00001", Price = 100}
    {Id = 2, Name = "Item2", Code = "IT00002", Price = 200}
    {Id = 3, Name = "Item3", Code = "IT00003", Price = 150}

    যা ভুল কারণ এটি {Id = 3, Name = "Item3", Code = "IT00004", Price = 250}সদৃশ হিসাবে বিবেচনা করে । সুতরাং সঠিক ক্যোয়ারীটি হ'ল:

    var distinctItems = a.GroupBy(c => new { c.Id , c.Name , c.Code , c.Price})
                         .Select(c => c.First()).ToList();

    3. ওভাররাইড Equalএবং GetHashCodeআইটেম শ্রেণিতে:

    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public int Price { get; set; }
    
        public override bool Equals(object obj)
        {
            if (!(obj is Item))
                return false;
            Item p = (Item)obj;
            return (p.Id == Id && p.Name == Name && p.Code == Code && p.Price == Price);
        }
        public override int GetHashCode()
        {
            return String.Format("{0}|{1}|{2}|{3}", Id, Name, Code, Price).GetHashCode();
        }
    }

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

    var distinctItems = a.Distinct();

11

একটি সর্বজনীন এক্সটেনশন পদ্ধতি:

public static class EnumerableExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
    {
        return enumerable.GroupBy(keySelector).Select(grp => grp.First());
    }
}

ব্যবহারের উদাহরণ:

var lstDst = lst.DistinctBy(item => item.Key);

খুব পরিষ্কার পদ্ধতির
স্টিভেন রাইসার্ট

4

এই এক্সটেনশন পদ্ধতিটি ব্যবহার করে দেখুন। আশা করি এটি সাহায্য করতে পারে।

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

ব্যবহার:

var outputList = sourceList.DistinctBy(x => x.TargetProperty);

3
List<Employee> employees = new List<Employee>()
{
    new Employee{Id =1,Name="AAAAA"}
    , new Employee{Id =2,Name="BBBBB"}
    , new Employee{Id =3,Name="AAAAA"}
    , new Employee{Id =4,Name="CCCCC"}
    , new Employee{Id =5,Name="AAAAA"}
};

List<Employee> duplicateEmployees = employees.Except(employees.GroupBy(i => i.Name)
                                             .Select(ss => ss.FirstOrDefault()))
                                            .ToList();

0

আর একটি কার্যনির্বাহী, ক্রয়যোগ্য সুন্দর নয়।

র‌্যাম মডিউলের তথ্য রেকর্ড করার জন্য আমার কাছে দুটি গ্রেট এবং "এসপিডি" হিসাবে দুটি গুণযুক্ত "এমইএমডিইএস" নামে একটি উপাদান সহ একটি এক্সএমএল ফাইল রয়েছে। এসপিডিতে প্রচুর দ্বৈত আইটেম রয়েছে।

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

        IEnumerable<XElement> MList =
            from RAMList in PREF.Descendants("MEMDES")
            where (string)RAMList.Attribute("GRADE") == "DDR4"
            select RAMList;

        List<string> sellist = new List<string>();

        foreach (var MEMList in MList)
        {
            sellist.Add((string)MEMList.Attribute("SPD").Value);
        }

        foreach (string slist in sellist.Distinct())
        {
            comboBox1.Items.Add(slist);
        }

-1

আপনি যখন আইকুয়ালিটি কম্পিউটার লিখতে চান না তখন আপনি নীচের মতো কিছু চেষ্টা করতে পারেন।

 class Program
{

    private static void Main(string[] args)
    {

        var items = new List<Item>();
        items.Add(new Item {Id = 1, Name = "Item1"});
        items.Add(new Item {Id = 2, Name = "Item2"});
        items.Add(new Item {Id = 3, Name = "Item3"});

        //Duplicate item
        items.Add(new Item {Id = 4, Name = "Item4"});
        //Duplicate item
        items.Add(new Item {Id = 2, Name = "Item2"});

        items.Add(new Item {Id = 3, Name = "Item3"});

        var res = items.Select(i => new {i.Id, i.Name})
            .Distinct().Select(x => new Item {Id = x.Id, Name = x.Name}).ToList();

        // now res contains distinct records
    }



}


public class Item
{
    public int Id { get; set; }

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