সি # লিংক তালিকায় সদৃশ সন্ধান করুন


333

লিনকিউ ব্যবহার করে, এ থেকে List<int>, আমি কীভাবে এমন একটি তালিকা পুনরুদ্ধার করতে পারি যাতে একাধিকবার পুনরাবৃত্তি এবং তাদের মানগুলি থাকে?

উত্তর:


567

সমস্যা সমাধানের সহজতম উপায় হ'ল উপাদানগুলির মানগুলির উপর ভিত্তি করে দলবদ্ধ করা এবং তারপরে গ্রুপে একাধিক উপাদান উপস্থিত থাকলে গ্রুপের প্রতিনিধি বাছাই করা। লিংক-এ, এটি অনুবাদ করে:

var query = lst.GroupBy(x => x)
              .Where(g => g.Count() > 1)
              .Select(y => y.Key)
              .ToList();

আপনি যদি উপাদানগুলি কতবার পুনরাবৃত্তি করতে চান তা জানতে আপনি ব্যবহার করতে পারেন:

var query = lst.GroupBy(x => x)
              .Where(g => g.Count() > 1)
              .Select(y => new { Element = y.Key, Counter = y.Count() })
              .ToList();

এটি Listএকটি বেনামি ধরণের একটি ফিরিয়ে দেবে , এবং প্রতিটি উপাদানগুলির বৈশিষ্ট্য Elementএবং Counterআপনার প্রয়োজনীয় তথ্য পুনরুদ্ধার করতে হবে।

এবং সবশেষে, এটি যদি আপনি অভিধান খুঁজছেন তবে এটি ব্যবহার করতে পারেন

var query = lst.GroupBy(x => x)
              .Where(g => g.Count() > 1)
              .ToDictionary(x => x.Key, y => y.Count());

এটি আপনার কী হিসাবে আপনার উপাদানটি সহ একটি অভিধান এবং এটির মান হিসাবে বারবার পুনরাবৃত্তি করবে।


এখন কেবল একটি আশ্চর্যজনকভাবে বলা যাক যে ডুপ্লিকেট করা ইন্টি এনটি অ্যারেগুলিতে বিতরণ করা হয়েছে, আমি অভিধান ব্যবহার করছি এবং লুপের জন্য কোন অ্যারেটিতে একটি সদৃশ রয়েছে এবং এটি বিতরণের যুক্তি অনুসারে মুছে ফেলা হবে, সেখানে কি দ্রুততম উপায় আছে (লিনক অবাক করে)? যে ফলাফল অর্জন? আগ্রহের জন্য আগাম ধন্যবাদ
মিরকো আরেসে

আমি এই জাতীয় কিছু করছি: code (int i = 0; i <সদৃশ। হিসাব; i ++) {int সদৃশ = নকল [i]; সদৃশ অবস্থান.এড করুন (সদৃশ, নতুন তালিকা <int> ()); (int k = 0; k <hitsList.Length; k ++) {if (hitsList [k] .Contains (সদৃশ)) {সদৃশ লোকেশন.এলিমেন্ট (i)। ভ্যালু .এড (কে); }} // কিছু নিয়ম অনুসারে সদৃশগুলি সরান। }code
মিরকো আরেসে

আপনি যদি অ্যারের তালিকায় নকল পেতে চান তবে সিলেক্টম্যানকে একবার দেখুন
সংরক্ষণ করুন

আমি তালিকার একটি অ্যারে সদৃশগুলি সন্ধান করছি, তবে নির্বাচক কীভাবে আমাকে এটি তৈরি করতে সহায়তা করতে পারে তা
পাননি

1
যে কোনও সংগ্রহে একাধিক উপাদান রয়েছে কিনা তা পরীক্ষা করতে স্কিপ (1) ব্যবহার করতে আরও দক্ষ কিনা। গণনা () এর পরিবর্তে যে কোনও () ব্যবহার করুন। 1000 উপাদান সহ একটি সংগ্রহের কল্পনা করুন। (1) এড়িয়ে যান। যে কোনও () শনাক্ত করতে পারে যে এটি 2 তম উপাদানটি খুঁজে পাওয়ার পরে 1 টিরও বেশি রয়েছে। গণনা () ব্যবহারের জন্য সম্পূর্ণ সংগ্রহ অ্যাক্সেস করতে হবে।
হ্যারাল্ড কপুলস

133

একটি গুণমানের কোনও সদৃশ রয়েছে কিনা তা সন্ধান করুন :

var anyDuplicate = enumerable.GroupBy(x => x.Key).Any(g => g.Count() > 1);

খুঁজে পাবেন যদি সব একটি গণনীয় মধ্যে মান অনন্য :

var allUnique = enumerable.GroupBy(x => x.Key).All(g => g.Count() == 1);

এগুলি কি সবসময় বুলিয়ান বিপরীত হয় না? যে কোনও ডুপ্লিকেট ==! সব ক্ষেত্রেই ইউনিক।
গার গডফ্রে

1
@ গারগোডফ্রে তারা সর্বদা বুলিয়ান বিপরীত হয়
ক্যালটার

21

আর একটি উপায় ব্যবহার করা হচ্ছে HashSet:

var hash = new HashSet<int>();
var duplicates = list.Where(i => !hash.Add(i));

আপনি যদি আপনার সদৃশ তালিকায় অনন্য মান চান:

var myhash = new HashSet<int>();
var mylist = new List<int>(){1,1,2,2,3,3,3,4,4,4};
var duplicates = mylist.Where(item => !myhash.Add(item)).Distinct().ToList();

এখানে জেনেরিক এক্সটেনশন পদ্ধতি হিসাবে একই সমাধান:

public static class Extensions
{
  public static IEnumerable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector, IEqualityComparer<TKey> comparer)
  {
    var hash = new HashSet<TKey>(comparer);
    return source.Where(item => !hash.Add(selector(item))).ToList();
  }

  public static IEnumerable<TSource> GetDuplicates<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
  {
    return source.GetDuplicates(x => x, comparer);      
  }

  public static IEnumerable<TSource> GetDuplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
  {
    return source.GetDuplicates(selector, null);
  }

  public static IEnumerable<TSource> GetDuplicates<TSource>(this IEnumerable<TSource> source)
  {
    return source.GetDuplicates(x => x, null);
  }
}

এটি প্রত্যাশার মতো কাজ করে না। List<int> { 1, 2, 3, 4, 5, 2 }উত্স হিসাবে ব্যবহার করে , ফলাফলটি এমন একটি IEnumerable<int>উপাদানের সাথে 1
বিসিএ 21

@ বিবিএ গতকাল, আমি মনে করি আপনি ভুল বলেছেন। এই উদাহরণটি দেখুন: ডটনেটফিডাল.এন.
হুবেজা

আপনার ফিডাল সঠিক ফলাফল মুদ্রণ করে। যাইহোক, আমি এর Console.WriteLine("Count: {0}", duplicates.Count());নীচে লাইনটি যুক্ত করেছি এবং এটি মুদ্রণ করে 6। আমি এই ফাংশনটির প্রয়োজনীয়তাগুলি সম্পর্কে কিছু অনুপস্থিত না করে ফলস্বরূপ সংগ্রহে কেবলমাত্র 1 টি আইটেম থাকা উচিত।
বিসিএ 13

গতকাল বিবিসিএ, এটি লিনকুই স্থগিতাদেশ কার্যকর করার ফলে একটি বাগ হয়েছে। আমি ToListসমস্যাটি সংশোধন করার জন্য যুক্ত করেছি , তবে এর অর্থ হল যে পদ্ধতিটি বলা হওয়ার সাথে সাথেই এটি কার্যকর করা হবে এবং আপনি ফলাফলগুলি পুনরুক্তি করার সময় নয়।
হুবেজা

var hash = new HashSet<int>(); var duplicates = list.Where(i => !hash.Add(i));ডুপ্লিকেটগুলির সমস্ত উপস্থিতি অন্তর্ভুক্ত একটি তালিকায় নিয়ে যাবে। সুতরাং আপনার তালিকায় যদি 2 টির চারটি উপস্থিতি থাকে তবে আপনার সদৃশ তালিকায় 2 টির তিনটি উপস্থিতি থাকবে, যেহেতু 2 এর মধ্যে একটিরও হ্যাশসেটে যুক্ত করা যায়। যদি আপনি চান যে আপনার তালিকায় প্রতিটি var duplicates = mylist.Where(item => !myhash.Add(item)).ToList().Distinct().ToList();
সদৃশটির

10

তুমি এটি করতে পারো:

var list = new[] {1,2,3,1,4,2};
var duplicateItems = list.Duplicates();

এই এক্সটেনশন পদ্ধতিগুলির সাথে:

public static class Extensions
{
    public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
    {
        var grouped = source.GroupBy(selector);
        var moreThan1 = grouped.Where(i => i.IsMultiple());
        return moreThan1.SelectMany(i => i);
    }

    public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source)
    {
        return source.Duplicates(i => i);
    }

    public static bool IsMultiple<T>(this IEnumerable<T> source)
    {
        var enumerator = source.GetEnumerator();
        return enumerator.MoveNext() && enumerator.MoveNext();
    }
}

সদৃশ পদ্ধতিতে ইসমুলটিপল () ব্যবহার করা গণনা () এর চেয়ে দ্রুততর কারণ এটি পুরো সংগ্রহকে পুনরাবৃত্তি করে না।


আপনি যদি গ্রুপিংয়ের জন্য রেফারেন্স উত্সটি দেখেন তবে আপনি দেখতে পাচ্ছেন যে Count() এটি প্রাক গণিত এবং আপনার সমাধান সম্ভবত ধীর।
জনবট

@Johnbot। আপনি ঠিক বলেছেন, এক্ষেত্রে এটি দ্রুত এবং বাস্তবায়ন কখনও পরিবর্তিত হওয়ার সম্ভাবনা নেই ... তবে এটি আইগ্রুপিংয়ের পিছনে বাস্তবায়ন শ্রেণীর প্রয়োগের বিশদটির উপর নির্ভর করে। আমার বাস্তবায়ন সহ, আপনি জানেন যে এটি কখনই পুরো সংগ্রহটি পুনরাবৃত্তি করে না।
অ্যালেক্স সিপম্যান

সুতরাং গণনা [ Count()] সম্পূর্ণ তালিকার পুনরাবৃত্তির চেয়ে মূলত আলাদা। Count()প্রাক-গণিত হয় তবে পুরো তালিকাটি পুনরাবৃত্তি করা হয় না।
জোগি

@ রেহান খান: আমি গণনা () এবং গণনা ()
অ্যালেক্স সিপম্যানের

2
@ রেহান খান: ইসমলটিপল কোনও গণনা করছে না (), এটি দুটি আইটেমের সাথে সাথেই বন্ধ হয়ে যায়। ঠিক যেমন টেক (2)। অ্যাকাউন্ট> = 2;
অ্যালেক্স সিপম্যান

6

আমি আপনার প্রকল্পগুলিতে এটি অন্তর্ভুক্ত করতে পারে এর প্রতিক্রিয়াটির জন্য আমি একটি উত্সাহ তৈরি করেছি, আমি মনে করি আপনি তালিকা বা লিনিকের অনুলিপি সন্ধান করার সময় এটি সবচেয়ে বেশি ফিরে আসে।

উদাহরণ:

//Dummy class to compare in list
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public Person(int id, string name, string surname)
    {
        this.Id = id;
        this.Name = name;
        this.Surname = surname;
    }
}


//The extention static class
public static class Extention
{
    public static IEnumerable<T> getMoreThanOnceRepeated<T>(this IEnumerable<T> extList, Func<T, object> groupProps) where T : class
    { //Return only the second and next reptition
        return extList
            .GroupBy(groupProps)
            .SelectMany(z => z.Skip(1)); //Skip the first occur and return all the others that repeats
    }
    public static IEnumerable<T> getAllRepeated<T>(this IEnumerable<T> extList, Func<T, object> groupProps) where T : class
    {
        //Get All the lines that has repeating
        return extList
            .GroupBy(groupProps)
            .Where(z => z.Count() > 1) //Filter only the distinct one
            .SelectMany(z => z);//All in where has to be retuned
    }
}

//how to use it:
void DuplicateExample()
{
    //Populate List
    List<Person> PersonsLst = new List<Person>(){
    new Person(1,"Ricardo","Figueiredo"), //fist Duplicate to the example
    new Person(2,"Ana","Figueiredo"),
    new Person(3,"Ricardo","Figueiredo"),//second Duplicate to the example
    new Person(4,"Margarida","Figueiredo"),
    new Person(5,"Ricardo","Figueiredo")//third Duplicate to the example
    };

    Console.WriteLine("All:");
    PersonsLst.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
    /* OUTPUT:
        All:
        1 -> Ricardo Figueiredo
        2 -> Ana Figueiredo
        3 -> Ricardo Figueiredo
        4 -> Margarida Figueiredo
        5 -> Ricardo Figueiredo
        */

    Console.WriteLine("All lines with repeated data");
    PersonsLst.getAllRepeated(z => new { z.Name, z.Surname })
        .ToList()
        .ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
    /* OUTPUT:
        All lines with repeated data
        1 -> Ricardo Figueiredo
        3 -> Ricardo Figueiredo
        5 -> Ricardo Figueiredo
        */
    Console.WriteLine("Only Repeated more than once");
    PersonsLst.getMoreThanOnceRepeated(z => new { z.Name, z.Surname })
        .ToList()
        .ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
    /* OUTPUT:
        Only Repeated more than once
        3 -> Ricardo Figueiredo
        5 -> Ricardo Figueiredo
        */
}

1
স্কিপ (1) ব্যবহার বিবেচনা করুন। গণনা () এর পরিবর্তে যে কোনও () ব্যবহার করুন। আপনার যদি 1000 টি সদৃশ থাকে তবে এড়িয়ে যান (1)। যে কোনও () এটি দ্বিতীয়টি খুঁজে পাওয়ার পরে থামবে। গণনা () সমস্ত 1000 উপাদানগুলিতে অ্যাক্সেস করবে।
হ্যারাল্ড কপুলস

1
আপনি যদি এই এক্সটেনশন পদ্ধতিটি যুক্ত করেন তবে অন্যান্য উত্তরগুলির মধ্যে একটিতে মিলে হিসাবে গ্রুপবি'র পরিবর্তে হ্যাশসেট ব্যবহার করুন। যত তাড়াতাড়ি হ্যাশসেট Aএই একটি সদৃশ পাওয়া যাবে এটি বন্ধ হয়ে যাবে। আপনার গ্রুপবাই সমস্ত উপাদানগুলির গোষ্ঠীকরণ অব্যাহত রাখবে, এমনকি যদি একাধিক উপাদান সহ একটি গোষ্ঠী পাওয়া যায়
হ্যারাল্ড কোপপুলস ২17

6

কেবলমাত্র সদৃশ মানগুলি সন্ধান করতে:

var duplicates = list.GroupBy(x => x.Key).Any(g => g.Count() > 1);

যেমন। var তালিকা = নতুন [] {1,2,3,1,4,2};

সুতরাং গোষ্ঠী অনুসারে সংখ্যাগুলি তাদের কী দ্বারা গোষ্ঠীভুক্ত করবে এবং এটির সাথে গণনাটি (এটি পুনরাবৃত্তির সংখ্যা) বজায় রাখবে। এর পরে, আমরা কেবল সেই মানগুলি যাচাই করছি যা একাধিকবার পুনরাবৃত্তি করেছে।

একমাত্র মানগুলি খুঁজে পেতে:

var unique = list.GroupBy(x => x.Key).All(g => g.Count() == 1);

যেমন। var তালিকা = নতুন [] {1,2,3,1,4,2};

সুতরাং গোষ্ঠী অনুসারে সংখ্যাগুলি তাদের কী দ্বারা গোষ্ঠীভুক্ত করবে এবং এটির সাথে গণনাটি (এটি পুনরাবৃত্তির সংখ্যা) বজায় রাখবে। এর পরে, আমরা কেবল সেই মানগুলি যাচাই করে যাঁরা কেবল একবারে পুনরাবৃত্তি করেছেন তার অর্থ অনন্য।


কোডের নীচে অনন্য আইটেমগুলিও খুঁজে পাবেন। var unique = list.Distinct(x => x)
মালু এমএন

1

এমএস এসকিউএল সার্ভারে চেক ডুপ্লিকেট ফাংশনগুলির লিনাক থেকে এসকিউএল এক্সটেনশনের সম্পূর্ণ সেট। .ToList () বা IEnumerable ব্যবহার না করে। এই ক্যোয়ারী মেমরির চেয়ে এসকিউএল সার্ভারে কার্যকর করা হচ্ছে। । ফলাফলগুলি কেবল স্মৃতিতে ফিরে আসে।

public static class Linq2SqlExtensions {

    public class CountOfT<T> {
        public T Key { get; set; }
        public int Count { get; set; }
    }

    public static IQueryable<TKey> Duplicates<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => s.Key);

    public static IQueryable<TSource> GetDuplicates<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).SelectMany(s => s);

    public static IQueryable<CountOfT<TKey>> DuplicatesCounts<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(y => new CountOfT<TKey> { Key = y.Key, Count = y.Count() });

    public static IQueryable<Tuple<TKey, int>> DuplicatesCountsAsTuble<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => Tuple.Create(s.Key, s.Count()));
}

0

একটি উত্তর আছে তবে আমি বুঝতে পারি না কেন কাজ করছে না;

var anyDuplicate = enumerable.GroupBy(x => x.Key).Any(g => g.Count() > 1);

আমার সমাধান এই পরিস্থিতিতে যেমন;

var duplicates = model.list
                    .GroupBy(s => s.SAME_ID)
                    .Where(g => g.Count() > 1).Count() > 0;
if(duplicates) {
    doSomething();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.