আমি পর্যবেক্ষণযোগ্য সংগ্রহকে কীভাবে বাছাই করব?


97

আমার নিম্নলিখিত ক্লাস রয়েছে:

[DataContract]
public class Pair<TKey, TValue> : INotifyPropertyChanged, IDisposable
{
    public Pair(TKey key, TValue value)
    {
        Key = key;
        Value = value;
    }

    #region Properties
    [DataMember]
    public TKey Key
    {
        get
        { return m_key; }
        set
        {
            m_key = value;
            OnPropertyChanged("Key");
        }
    }
    [DataMember]
    public TValue Value
    {
        get { return m_value; }
        set
        {
            m_value = value;
            OnPropertyChanged("Value");
        }
    }
    #endregion

    #region Fields
    private TKey m_key;
    private TValue m_value;
    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    { }

    #endregion
}

যা আমি একটি পর্যবেক্ষণযোগ্য সংগ্রহের মধ্যে রেখেছি:

ObservableCollection<Pair<ushort, string>> my_collection = 
    new ObservableCollection<Pair<ushort, string>>();

my_collection.Add(new Pair(7, "aaa"));
my_collection.Add(new Pair(3, "xey"));
my_collection.Add(new Pair(6, "fty"));

প্রশ্ন: কীভাবে আমি এটি কী দ্বারা বাছাই করব?


আপনি কি ক্লাসের মধ্যে বাছাইয়ের প্রয়োগের সন্ধান করছেন বা কেবল যে কোনও ধরণের বাছাই করবে?
okw

কীভাবে বুঝতে হবে তা নিশ্চিত নয়। মূলত আমি কেবল এটি বাছাই করতে চাই, সংগ্রহটি খুব বড় হতে যাচ্ছে না (20 আইটেম সর্বাধিক) তাই যে কোনও কিছুই করা হবে (সম্ভবত)
ম্যাকিক

একটি WPF সমাধান জন্য এই দেখুন stackoverflow.com/questions/1945461/...
Gayot Fow

এই পৃষ্ঠায় উত্তরগুলি দেখুন: একটি ভাঙা API এর খুব স্পষ্ট ইঙ্গিত যখন এটি কিছু সমালোচনামূলক এবং মৌলিক কার্যকারিতার জন্য 22+ উত্তর নেয়।
গেরি

উত্তর:


21

পর্যবেক্ষণযোগ্য বাছাই করা এবং একই জিনিস সাজানো ফেরত দেওয়া একটি এক্সটেনশন পদ্ধতি ব্যবহার করে করা যায়। বৃহত্তর সংগ্রহের জন্য সংগ্রহের পরিবর্তিত বিজ্ঞপ্তির সংখ্যার দিকে নজর রাখুন।

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

public static void Sort<T>(this ObservableCollection<T> collection)
        where T : IComparable<T>, IEquatable<T>
    {
        List<T> sorted = collection.OrderBy(x => x).ToList();

        int ptr = 0;
        while (ptr < sorted.Count - 1)
        {
            if (!collection[ptr].Equals(sorted[ptr]))
            {
                int idx = search(collection, ptr+1, sorted[ptr]);
                collection.Move(idx, ptr);
            }
            
            ptr++;
        }
    }

    public static int search<T>(ObservableCollection<T> collection, int startIndex, T other)
            {
                for (int i = startIndex; i < collection.Count; i++)
                {
                    if (other.Equals(collection[i]))
                        return i;
                }
    
                return -1; // decide how to handle error case
            }

ব্যবহার: একটি পর্যবেক্ষকের সাথে নমুনা (এটি সহজ রাখতে একজন ব্যক্তি শ্রেণি ব্যবহৃত হয়)

    public class Person:IComparable<Person>,IEquatable<Person>
            { 
                public string Name { get; set; }
                public int Age { get; set; }
    
                public int CompareTo(Person other)
                {
                    if (this.Age == other.Age) return 0;
                    return this.Age.CompareTo(other.Age);
                }
    
                public override string ToString()
                {
                    return Name + " aged " + Age;
                }
    
                public bool Equals(Person other)
                {
                    if (this.Name.Equals(other.Name) && this.Age.Equals(other.Age)) return true;
                    return false;
                }
            }
    
          static void Main(string[] args)
            {
                Console.WriteLine("adding items...");
                var observable = new ObservableCollection<Person>()
                {
                    new Person {Name = "Katy", Age = 51},
                    new Person {Name = "Jack", Age = 12},
                    new Person {Name = "Bob", Age = 13},
                    new Person {Name = "Alice", Age = 39},
                    new Person {Name = "John", Age = 14},
                    new Person {Name = "Mary", Age = 41},
                    new Person {Name = "Jane", Age = 20},
                    new Person {Name = "Jim", Age = 39},
                    new Person {Name = "Sue", Age = 5},
                    new Person {Name = "Kim", Age = 19}
                };
    
                //what do observers see?
            
    
observable.CollectionChanged += (sender, e) =>
        {
            Console.WriteLine(
                e.OldItems[0] + " move from " + e.OldStartingIndex + " to " + e.NewStartingIndex);
            int i = 0;
            foreach (var person in sender as ObservableCollection<Person>)
            {
                if (i == e.NewStartingIndex)
                {
                    Console.Write("(" + (person as Person).Age + "),");
                }
                else
                {
                    Console.Write((person as Person).Age + ",");
                }
                
                i++;
            }

            Console.WriteLine();
        };

সংগ্রহটি কীভাবে করা হয় তা দেখিয়ে অগ্রগতি বাছাইয়ের বিশদ:

Sue aged 5 move from 8 to 0
(5),51,12,13,39,14,41,20,39,19,
Jack aged 12 move from 2 to 1
5,(12),51,13,39,14,41,20,39,19,
Bob aged 13 move from 3 to 2
5,12,(13),51,39,14,41,20,39,19,
John aged 14 move from 5 to 3
5,12,13,(14),51,39,41,20,39,19,
Kim aged 19 move from 9 to 4
5,12,13,14,(19),51,39,41,20,39,
Jane aged 20 move from 8 to 5
5,12,13,14,19,(20),51,39,41,39,
Alice aged 39 move from 7 to 6
5,12,13,14,19,20,(39),51,41,39,
Jim aged 39 move from 9 to 7
5,12,13,14,19,20,39,(39),51,41,
Mary aged 41 move from 9 to 8
5,12,13,14,19,20,39,39,(41),51,

ব্যক্তি শ্রেণি আইকোপ্যামেবল এবং আইক্যায়েটেবল উভয়ই প্রয়োগ করে তবে পরবর্তীটি সংগ্রহের পরিবর্তনগুলি হ্রাস করতে ব্যবহৃত হয় যাতে উত্থাপিত পরিবর্তনের বিজ্ঞপ্তিগুলির সংখ্যা হ্রাস করতে পারে

  • একটি নতুন অনুলিপি তৈরি না করেই সম্পাদনা একই সংগ্রহের বাছাই করে *

একটি পর্যবেক্ষণযোগ্য সংগ্রহ ফিরিয়ে আনার জন্য, কল করুন। টোগো অবজার্ভেবল কালেকশন * সর্ডটোক * এ যেমন [এই বাস্তবায়ন] [1] ব্যবহার করে।

**** মূল উত্তর - এটি একটি নতুন সংগ্রহ তৈরি করে **** আপনি নীচের ডোসর্ট পদ্ধতি হিসাবে লিঙ্ক ব্যবহার করতে পারেন illust একটি দ্রুত কোড স্নিপেট: উত্পাদন করে

3: এক্সে 6: এফটি 7: আআ

বিকল্পভাবে আপনি সংগ্রহটিতে নিজেই একটি এক্সটেনশন পদ্ধতি ব্যবহার করতে পারেন

var sortedOC = _collection.OrderBy(i => i.Key);

private void doSort()
{
    ObservableCollection<Pair<ushort, string>> _collection = 
        new ObservableCollection<Pair<ushort, string>>();

    _collection.Add(new Pair<ushort,string>(7,"aaa"));
    _collection.Add(new Pair<ushort, string>(3, "xey"));
    _collection.Add(new Pair<ushort, string>(6, "fty"));

    var sortedOC = from item in _collection
                   orderby item.Key
                   select item;

    foreach (var i in sortedOC)
    {
        Debug.WriteLine(i);
    }

}

public class Pair<TKey, TValue>
{
    private TKey _key;

    public TKey Key
    {
        get { return _key; }
        set { _key = value; }
    }
    private TValue _value;

    public TValue Value
    {
        get { return _value; }
        set { _value = value; }
    }
    
    public Pair(TKey key, TValue value)
    {
        _key = key;
        _value = value;

    }

    public override string ToString()
    {
        return this.Key + ":" + this.Value;
    }
}

এটি খুঁজে পেয়েছে এবং এটি সবচেয়ে সহায়ক ou এটি কি লিনকুই সোর্টকড ওয়ার্ক তৈরি করে?
Jason94

9
এই উত্তরের অনুরাগী নন কারণ এটি আপনাকে একটি সাজানো পর্যবেক্ষণযোগ্য সংগ্রহ দেয় না।
xr280xr

63
-1 থেকে তা বাছাই করে না , কিন্তু এর পরিবর্তে একটি নতুন সংগ্রহ তৈরি করে। ObservableCollection
কোস

4
আপডেট করা কোডটি কাজ করবে তবে ও (এন ^ 2) সময়ের জটিলতা রয়েছে। এই ব্যবহার করে হে (ঢ * লগ (ঢ)) এর উন্নত করা যায় BinarySearchপরিবর্তে IndexOf
উইলিয়াম মরিসন

4
দুর্দান্ত সমাধান! পর্যবেক্ষণযোগ্য সংগ্রহ <টি> থেকে উত্তরাধিকারীদের জন্য, সরানোআউট এবং সন্নিবেশ পদ্ধতিগুলি ব্যবহার না করে সুরক্ষিত মুভি আইটেম () পদ্ধতি ব্যবহার করা সম্ভব। আরও দেখুন: রেফারেন্সসোর্স.মাইক্রোসফট
হারমান কর্ডেস

85

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

static class Extensions
{
    public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable
    {
        List<T> sorted = collection.OrderBy(x => x).ToList();
        for (int i = 0; i < sorted.Count(); i++)
            collection.Move(collection.IndexOf(sorted[i]), i);
    }
}

public class MyObject: IComparable
{
    public int CompareTo(object o)
    {
        MyObject a = this;
        MyObject b = (MyObject)o;
        return Utils.LogicalStringCompare(a.Title, b.Title);
    }

    public string Title;

}
  .
  .
  .
myCollection = new ObservableCollection<MyObject>();
//add stuff to collection
myCollection.Sort();

7
এই উত্তরটি হওয়া উচিত
থাম্বমুনকিজ

4
এটি উপরে গৃহীত আমার উত্তরটি আপডেট করেছে কারণ এটি গৃহীত প্রতিক্রিয়া এবং এই উত্তরের সাথে পারফরম্যান্সের উন্নতি সম্বোধন করে যা সংগ্রহের সমস্ত কিছুর জন্য পরিবর্তন বিজ্ঞপ্তি উত্থাপন করে
অ্যান্ড্রু

4
দুর্দান্ত উত্তর। এর return Utils.LogicalStringCompare(a.Title, b.Title);পরিবর্তে আপনি কেন ব্যবহার করছেন return string.Compare(a.Title, b.Title);? @ নিলডাব্লু
জো

4
@ জো, আমার একটি স্ট্যান্ডার্ড স্ট্রিং তুলনার পরিবর্তে লজিক্যাল তুলনা করা দরকার ছিল, এজন্য আমাকে প্রথম স্থানে এক্সটেনশনটি লেখার প্রয়োজন হয়েছিল। লজিকাল স্ট্রিংগুলি স্ট্রিংগুলিতে স্ট্রিংয়ের মতো ক্রমান্বয়ে সংখ্যার তুলনা করে (1, 1000, 2, 20 ইত্যাদির পরিবর্তে 1, 2, 20, 1000)
নিলডব্লু 8'15

4
এই একেবারে যেতে উপায়। আমি এটি নিজের প্রসারিত করার একটি উত্তর যুক্ত করেছি, আপনাকে আইএনকম্পারেবল ব্যবহারের পরিবর্তে কী-সিলেক্টারে পাস করার অনুমতি দিয়েছি, যেমন লিনকিউ সাধারণত করে।
জোনেসোপলিস

39

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

http://kiwigis.blogspot.com/2010/03/how-to-sort-obversablecollection.html

হালনাগাদ

ObservableSortedList যে মন্তব্য আউট @romkyns পয়েন্ট স্বয়ংক্রিয়ভাবে সাজানোর ক্রম বজায় রাখে।

একটি পর্যবেক্ষণযোগ্য সংগ্রহ কার্যকর করে যা এর আইটেমগুলি সাজানো ক্রমে পরিচালনা করে। বিশেষত, আইটেমের বৈশিষ্ট্যগুলিতে পরিবর্তনগুলি যার ফলে অর্ডারের পরিবর্তনগুলি সঠিকভাবে পরিচালনা করা হয়।

তবে মন্তব্যটিও নোট করুন

জড়িত ইন্টারফেসের তুলনামূলক জটিলতা এবং এর তুলনামূলক দুর্বল ডকুমেন্টেশনের কারণে বগি হতে পারে ( https://stackoverflow.com/a/5883947/33080 দেখুন )।


4
প্রকৃতপক্ষে, এই ব্লগটি আরও দরকারী। যাইহোক, আমি পর্যবেক্ষণযোগ্য সংগ্রহ যা আইটেমগুলি যোগ করা এবং অপসারণের কারণে এর বাছাই বজায় রাখার প্রশ্নটির একটি সুনির্দিষ্ট উত্তর খুঁজে পাই না। আমি আমার নিজের লিখতে যাচ্ছি আমার মনে হয়।
স্টিফেন ড্রু

@Steve আপনি চেষ্টা করতে পারেন এই এক
রোমান স্টারকভ

লিঙ্কটির জন্য ধন্যবাদ, আমি পরিসমাপ্তির পদ্ধতির সাথে গিয়েছিলাম কারণ এটি পরিপাটি সমাধান মনে হয়েছিল।
মোহন

bw কেউ কি খেয়াল করেছেন যে এইচটিএমএল ফাইলের নামটিতে (ওভারসেবলকোলিকেশন) ব্লগে টাইপ রয়েছে? : পি
লাইশিকাই

4
@ আরমকিন্সের উত্তরটি ছিল পর্যবেক্ষণযোগ্য সংগ্রহ <টি> প্রসারিত করা। গ্রিডভিউ এটিকে ঠিক তখনই স্বীকৃতি দেয়। তারপরে কেবল তার মতো পদ্ধতিগুলি গোপন করুন। আমি সময় পেলে একটি সম্পূর্ণ সমাধান পোস্ট করব।
ওয়েস্টন

25

আপনি এই সহজ পদ্ধতিটি ব্যবহার করতে পারেন:

public static void Sort<TSource, TKey>(this Collection<TSource> source, Func<TSource, TKey> keySelector)
{
    List<TSource> sortedList = source.OrderBy(keySelector).ToList();
    source.Clear();
    foreach (var sortedItem in sortedList)
        source.Add(sortedItem);
}

আপনি এটির মতো বাছাই করতে পারেন:

_collection.Sort(i => i.Key);

4
এটি পর্যবেক্ষণযোগ্য সংগ্রহটি পরিষ্কার করে তারপরে সমস্ত বস্তু পুনরায় যুক্ত করে - সুতরাং এটি লক্ষণীয় যে আপনার ইউআই যদি সংগ্রহের সাথে আবদ্ধ থাকে তবে আপনি অ্যানিমেটেড পরিবর্তনগুলি দেখতে পাবেন না, যেমন যখন আইটেমগুলি সরানো হয়
কার্লোস পি

4
আমি নিশ্চিত না কেন আপনি কেন আইটেমগুলি ঘুরে বেড়াতে হবে ... যেমন আপনি সাধারণত ObservableCollectionড্রপডাউনগুলির আইটেমসোর্সে আবদ্ধ হন এবং আপনি সংগ্রহটি মোটেও দেখতে পাচ্ছেন না। এছাড়াও ক্লিয়ার-আউট এবং ফিল-আপের এই অপারেশনটি অতি দ্রুত ... "ধীর" একটি ইতিমধ্যে অনুকূলিত হওয়া বাছাই করা যেতে পারে। অবশেষে, আপনার সরানো পদ্ধতিটি কার্যকর করার জন্য আপনি এই কোডটি সংশোধন করতে পারেন, sortedlistএবং sourceবাকিটি থাকা সহজ।
জায়েদার

4
আপনি যদি ড্রপ-ডাউন করতে আবদ্ধ হন তবে আইটেমগুলি ঘুরে দেখে আপনি কোনও উপকার পাবেন না, এটি সত্য। যদি আপনি যদি কোনও তালিকাবক্সের কাছে আবদ্ধ হন তবে ডাব্লুপিএফ বা সিলভারলাইট বা উইন্ডোজ স্টোর অ্যাপ্লিকেশনগুলির মতো ফ্রেমওয়ার্কগুলি দরকারী ভিজ্যুয়াল প্রতিক্রিয়া সরবরাহ করবে কারণ সংগ্রহের অবজেক্টগুলি পুনরায় সূচিকৃত হয়।
কার্লোস পি

এটি সরানোর পদ্ধতির চেয়ে দ্রুততর, এটি সংখ্যক রিসেট / অ্যাড ইভেন্টগুলি উত্থাপন করে। সর্বাধিক ভোট দেওয়া উত্তর (সরানো পদ্ধতির) এটিকে হ্রাস করে এবং যথাযথভাবে Moveইভেন্টগুলি উত্থাপন করে, এটিও কেবল সত্যিকারের স্থানান্তরিতদের জন্য।
নওফাল

20

ডাব্লুপিএফListCollectionView ক্লাসটি ব্যবহার করে বাক্সের বাইরে লাইভ বাছাই করে ...

public ObservableCollection<string> MyStrings { get; set; }
private ListCollectionView _listCollectionView;
private void InitializeCollection()
{
    MyStrings = new ObservableCollection<string>();
    _listCollectionView = CollectionViewSource.GetDefaultView(MyStrings) 
              as ListCollectionView;
    if (_listCollectionView != null)
    {
        _listCollectionView.IsLiveSorting = true;
        _listCollectionView.CustomSort = new 
                CaseInsensitiveComparer(CultureInfo.InvariantCulture);
    }
}

এই সূচনাটি সম্পূর্ণ হয়ে গেলে, আর কিছুই করার নেই। একটি প্যাসিভ সাজানোর উপর সুবিধা হ'ল লিস্টক্লিকেশন ভিউ সমস্ত ভারী উত্তোলন এমনভাবে করে যা বিকাশকারীর কাছে স্বচ্ছ। নতুন আইটেমগুলি স্বয়ংক্রিয়ভাবে তাদের সঠিক সাজানোর ক্রমে স্থাপন করা হয়। IComparerটি থেকে প্রাপ্ত যে কোনও শ্রেণি কাস্টম বাছাই করার সম্পত্তি জন্য উপযুক্ত।

ডকুমেন্টেশন এবং অন্যান্য বৈশিষ্ট্যগুলির জন্য তালিকা সংগ্রহকরণ ভিউ দেখুন ।


6
যা আসলে কাজ করেছিল: ডি এটি এতো সাধারণ কাজের জন্য অন্য "ওভাররিঞ্জাইনার্ড" সমাধানের চেয়ে আরও ভাল সমাধান।
মুশপিস

"স্বচ্ছ" জিনিসগুলির সমস্যা হ'ল এটি যখন কাজ করে না তখন কোথায় দেখতে হবে তা আপনি দেখতে পাচ্ছেন না। মাইক্রোসফ্টের ডকুমেন্টেশনের একটি 100% স্বচ্ছ উদাহরণ রয়েছে, আপনি এটি একেবারেই দেখতে পারবেন না।
পল ম্যাকার্থি

15

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

    public static void Sort<TSource, TKey>(this ObservableCollection<TSource> source, Func<TSource, TKey> keySelector)
    {
        if (source == null) return;

        Comparer<TKey> comparer = Comparer<TKey>.Default;

        for (int i = source.Count - 1; i >= 0; i--)
        {
            for (int j = 1; j <= i; j++)
            {
                TSource o1 = source[j - 1];
                TSource o2 = source[j];
                if (comparer.Compare(keySelector(o1), keySelector(o2)) > 0)
                {
                    source.Remove(o1);
                    source.Insert(j, o1);
                }
            }
        }
    }

আপনি যেভাবে কল করবেন ঠিক একইভাবে আপনি অর্ডারবিকে কল করবেন তা বাদ দিয়ে এটি কোনও নতুন সংগ্রহ ফেরত দেওয়ার পরিবর্তে আপনার পর্যবেক্ষণযোগ্য সংগ্রহের বিদ্যমান উদাহরণটি বাছাই করবে:

ObservableCollection<Person> people = new ObservableCollection<Person>();
...

people.Sort(p => p.FirstName);

4
এটি পোস্ট করার জন্য ধন্যবাদ - রিচির ব্লগে মন্তব্যগুলিতে যেমন উল্লেখ করা হয়েছে, এই কোডটিতে কিছু সার্থক বর্ধন রয়েছে; বিশেষত উত্সটির 'সরান' পদ্ধতিটি ব্যবহার করে। আমার ধারণা এটি উত্সের সাথে সরান / সন্নিবেশিত রেখাগুলি প্রতিস্থাপন করবে ove
কার্লোস পি

4
এই ধরণের অ্যালগরিদমটি অনুকূলিত করা হয়নি en.wikedia.org/wiki/Sorting_algorithm
জায়েদার

@ জয়দার হ্যাঁ, এটি সামগ্রিক কাঁচা গতির জন্য নয়, এটি অনুকূলিত।
jv42

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

11

রিয়েল ইন-প্লেস বাছাই করার জন্য @ নীলডাব্লু এর উত্তর হ'ল উপায়। আমি একটি সামান্য পরিবর্তিত সমাধান যুক্ত করতে চেয়েছিলাম যা আপনাকে ব্যবহারের বাইপাস করতে দেয় IComparable:

static class Extensions
{
    public static void Sort<TSource, TKey>(this ObservableCollection<TSource> collection, Func<TSource, TKey> keySelector)
    {
        List<TSource> sorted = collection.OrderBy(keySelector).ToList();
        for (int i = 0; i < sorted.Count(); i++)
            collection.Move(collection.IndexOf(sorted[i]), i);
    }
}

এখন আপনি এটিকে যে কোনও লিংক পদ্ধতির মতো কল করতে পারেন:

myObservableCollection.Sort(o => o.MyProperty);

4
অতিরিক্ত চকোলেট কুকির জন্য আপনি একটি বুলিয়ান প্যারামিটার "আরোহী" এবং এর if(!Ascending) sorted.Reverse();ঠিক আগে যুক্ত করতে পারেন for: ডি (এবং - মেমরি সম্পর্কে আরও চিন্তা করার দরকার নেই, যে বিপরীত পদ্ধতি কোনও নতুন অবজেক্ট তৈরি করে না, এটি স্থানের বিপরীতে রয়েছে)
শার্কি

আমার পরীক্ষাগুলির সংগ্রহ অনুসারে ove সুতরাং এটি সরানো এমনকি প্রয়োজনীয় কিনা তা প্রথমে পরীক্ষা করা একটি পারফরম্যান্স উন্নতি হতে চাই ment
sa.he

10

আমি চাই NeilW এর উত্তর যোগ করুন । অর্ডারবির অনুরূপ একটি পদ্ধতি অন্তর্ভুক্ত করা। এক্সটেনশন হিসাবে এই পদ্ধতিটি যুক্ত করুন:

public static void Sort<T>(this ObservableCollection<T> collection, Func<T,T> keySelector) where T : IComparable
{
    List<T> sorted = collection.OrderBy(keySelector).ToList();
    for (int i = 0; i < sorted.Count(); i++)
        collection.Move(collection.IndexOf(sorted[i]), i);
}

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

myCollection = new ObservableCollection<MyObject>();

//Sorts in place, on a specific Func<T,T>
myCollection.Sort(x => x.ID);

8

একটি পরিবর্তন হ'ল যেখানে আপনি নির্বাচনের বাছাই অ্যালগরিদম ব্যবহার করে সংগ্রহটিকে স্থানে সাজানMoveপদ্ধতিটি ব্যবহার করে উপাদানগুলিকে জায়গায় স্থানান্তরিত করা হয় । প্রতিটি পদক্ষেপ CollectionChangedইভেন্টের সাথে NotifyCollectionChangedAction.Move(এবং PropertyChangedসম্পত্তি নামের সাথে Item[]) আগুন দেবে ।

এই অ্যালগরিদমের কিছু দুর্দান্ত বৈশিষ্ট্য রয়েছে:

  • অ্যালগরিদম একটি স্থিতিশীল বাছাই হিসাবে প্রয়োগ করা যেতে পারে।
  • সংগ্রহের মধ্যে সরানো আইটেমের সংখ্যা (যেমন CollectionChangedইভেন্টগুলি বহিস্কার করা) সন্নিবেশ সাজানোর এবং বুদ্বুদ সাজানোর মতো অন্যান্য অনুরূপ অ্যালগরিদমের তুলনায় প্রায় সর্বদা কম।

অ্যালগরিদম বেশ সহজ। সংগ্রহটি ছোট আকারের উপাদানটি খুঁজতে পুনরুক্তি করা হয় যা পরে সংগ্রহের শুরুতে স্থানান্তরিত হয়। প্রক্রিয়াটি দ্বিতীয় উপাদান থেকে শুরু করে পুনরাবৃত্তি করা হয় এবং যতক্ষণ না সমস্ত উপাদানগুলিকে জায়গায় স্থান না দেওয়া হয়। অ্যালগরিদম মারাত্মকভাবে দক্ষ নয় তবে যে কোনও কিছুর জন্য আপনি কোনও ইউজার ইন্টারফেসে প্রদর্শন করতে যাচ্ছেন তা গুরুত্বপূর্ণ নয়। তবে মুভ অপারেশনের সংখ্যার দিক থেকে এটি বেশ দক্ষ।

এখানে একটি এক্সটেনশন পদ্ধতি রয়েছে যা সরলতার জন্য প্রয়োজনীয় উপাদানগুলি প্রয়োগ করে IComparable<T>। অন্যান্য বিকল্পগুলি একটি IComparer<T>বা একটি ব্যবহার করছে Func<T, T, Int32>

public static class ObservableCollectionExtensions {

  public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable<T> {
    if (collection == null)
      throw new ArgumentNullException("collection");

    for (var startIndex = 0; startIndex < collection.Count - 1; startIndex += 1) {
      var indexOfSmallestItem = startIndex;
      for (var i = startIndex + 1; i < collection.Count; i += 1)
        if (collection[i].CompareTo(collection[indexOfSmallestItem]) < 0)
          indexOfSmallestItem = i;
      if (indexOfSmallestItem != startIndex)
        collection.Move(indexOfSmallestItem, startIndex);
    }
  }

}

কোনও সংগ্রহ বাছাই করা কেবল এক্সটেনশন পদ্ধতিটি চাওয়ার বিষয়:

var collection = new ObservableCollection<String>(...);
collection.Sort();

4
এখানে বর্ণিত সমস্ত থেকে এটি আমার পছন্দের বাছাইয়ের উপায়, দুর্ভাগ্যক্রমে সরানো পদ্ধতিটি সিলভারলাইট 5 তে পাওয়া যায় না
এডুয়ার্ডো ব্রিটিস

4
আমি ত্রুটি পেয়েছি 'প্রোফাইলার.প্রফিল.প্রফিলওবজেক্ট' জেনেরিক টাইপ বা পদ্ধতিতে 'অবজারেবল কালেকশন এক্সটেনশনস.সর্ট করুন <টি> (পর্যবেক্ষণযোগ্য সংগ্রহ <টি>)' তে টাইপ প্যারামিটার 'টি' হিসাবে ব্যবহার করা যাবে না। 'প্রোফাইল.প্রফিলি.প্রফিলওবজেক্ট' থেকে 'সিস্টেম.আইকম্পেবল <প্রোফাইলার.প্রফিল.প্রফিলিঅবজেক্ট>
নিউ বি

4
@NewBee: এই এক্সটেনশনটি পদ্ধতি নির্দিষ্ট করে জেনেরিক বাধ্যতা উপর Tসংগ্রহে উপাদান বাছাই পাবে। বাছাইয়ের ক্ষেত্রে বৃহত্তর এবং কমের ধারণা জড়িত এবং কেবলমাত্র আপনি ProfileObjectঅর্ডার করা হয় তা নির্ধারণ করতে পারেন । এক্সটেনশন পদ্ধতিটি ব্যবহার করতে আপনাকে প্রয়োগ করতে IComparable<ProfileObject>হবে ProfileObject। অন্যান্য বিকল্পগুলি একটি IComparer<ProfileObject>বা একটি নির্দিষ্ট করে উল্লেখ করা হয় Func<ProfileObject, ProfileObject, int>এবং সেই অনুসারে বাছাইকরণ কোডটি পরিবর্তন করা হয়।
মার্টিন লিভারেজ

4

Xr280xr উত্তরে এক্সটেনশন পদ্ধতিটি কিছুটা উন্নত করার জন্য আমি বাছাই করা বাছাই হচ্ছে কিনা তা নির্ধারণের জন্য একটি alচ্ছিক বুল প্যারামিটার যুক্ত করেছি। আমি সেই উত্তরের মন্তব্যে কার্লোস পি দ্বারা প্রদত্ত পরামর্শও অন্তর্ভুক্ত করেছি। দয়া করে নীচে দেখুন.

public static void Sort<TSource, TKey>(this ObservableCollection<TSource> source, Func<TSource, TKey> keySelector, bool desc = false)
    {
        if (source == null) return;

        Comparer<TKey> comparer = Comparer<TKey>.Default;

        for (int i = source.Count - 1; i >= 0; i--)
        {
            for (int j = 1; j <= i; j++)
            {
                TSource o1 = source[j - 1];
                TSource o2 = source[j];
                int comparison = comparer.Compare(keySelector(o1), keySelector(o2));
                if (desc && comparison < 0)
                    source.Move(j, j - 1);
                else if (!desc && comparison > 0)
                    source.Move(j - 1, j);
            }
        }
    }

2

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

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

আপনার সংগ্রহটি যদি প্রয়োজন হয় তবে কয়েকবার ব্যবহার করুন:

my_collection.OrderBy(p => p.Key);

সংগ্রহটি বাছাই করতে এটি কিছুটা সময় নেবে, তবে তা সত্ত্বেও, আপনি এটি কী করছেন তার উপর নির্ভর করে এটি সেরা সমাধান হতে পারে।


4
এই উত্তরের লিঙ্কটি এলজিপিএল লাইসেন্স কোডটি, তাই যদি আপনি সিলভারলাইট (ডায়নামালি লিঙ্ক করতে পারেন না) বা ওপেন সোর্স না হন তবে সেই কোডটি সম্পর্কে সতর্ক থাকুন।
yzorg

2

আমার বর্তমান উত্তরে ইতিমধ্যে সর্বাধিক ভোট রয়েছে, তবে আমি এটি করার একটি আরও ভাল এবং আরও আধুনিক found

class MyObject 
{
      public int id { get; set; }
      public string title { get; set; }
}

ObservableCollection<MyObject> myCollection = new ObservableCollection<MyObject>();

//add stuff to collection
// .
// .
// .

myCollection = new ObservableCollection<MyObject>(
    myCollection.OrderBy(n => n.title, Comparer<string>.Create(
    (x, y) => (Utils.Utils.LogicalStringCompare(x, y)))));

মূল উত্তরটি আপডেট করা ভাল না?
নাথান হিউজেস

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

1

একটি নতুন শ্রেণি তৈরি করুন SortedObservableCollection, এটিকে থেকে ObservableCollectionপ্রয়োগ করুন এবং বাস্তবায়ন করুন IComparable<Pair<ushort, string>>


1

একটি উপায় হ'ল এটিকে একটি তালিকায় রূপান্তর করা এবং তারপরে একটি তুলনামূলক প্রতিনিধি সরবরাহ করা বাছাই করুন () call কিছুটা এইরকম:-

(স্বাক্ষরিত)

my_collection.ToList().Sort((left, right) => left == right ? 0 : (left > right ? -1 : 1));

1

হ্যাক কী, আমি দ্রুত-মুচিল-একসাথে উত্তরও ফেলে দেব ... এটি এখানে অন্য কয়েকটি বাস্তবায়নের মতো দেখতে বেশ কিছুটা লাগে তবে আমি এটিকে যেকোনভাবে যুক্ত করব:

(সবেমাত্র পরীক্ষা করা হয়েছে, আশা করছি আমি নিজেকে জড়িয়ে ধরছি না)

আসুন প্রথমে কিছু লক্ষ্য বর্ণনা করি (আমার অনুমান):

1) ObservableCollection<T>বিজ্ঞপ্তিগুলি বজায় রাখার জন্য, স্থানে বাছাই করতে হবে

2) অবশ্যই মারাত্মকভাবে অদক্ষ হওয়া উচিত নয় (অর্থাত্, স্ট্যান্ডার্ড "ভাল" বাছাইয়ের দক্ষতার কাছাকাছি কিছু )

public static class Ext
{
    public static void Sort<T>(this ObservableCollection<T> src)
        where T : IComparable<T>
    {
        // Some preliminary safety checks
        if(src == null) throw new ArgumentNullException("src");
        if(!src.Any()) return;

        // N for the select,
        // + ~ N log N, assuming "smart" sort implementation on the OrderBy
        // Total: N log N + N (est)
        var indexedPairs = src
            .Select((item,i) => Tuple.Create(i, item))
            .OrderBy(tup => tup.Item2);
        // N for another select
        var postIndexedPairs = indexedPairs
            .Select((item,i) => Tuple.Create(i, item.Item1, item.Item2));
        // N for a loop over every element
        var pairEnum = postIndexedPairs.GetEnumerator();
        pairEnum.MoveNext();
        for(int idx = 0; idx < src.Count; idx++, pairEnum.MoveNext())
        {
            src.RemoveAt(pairEnum.Current.Item1);
            src.Insert(idx, pairEnum.Current.Item3);            
        }
        // (very roughly) Estimated Complexity: 
        // N log N + N + N + N
        // == N log N + 3N
    }
}

1

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

public class ScoutItems : ObservableCollection<ScoutItem>
{
    public void Sort(SortDirection _sDir, string _sItem)
    {
             //TODO: Add logic to look at _sItem and decide what property to sort on
            IEnumerable<ScoutItem> si_enum = this.AsEnumerable();

            if (_sDir == SortDirection.Ascending)
            {
                si_enum = si_enum.OrderBy(p => p.UPC).AsEnumerable();
            } else
            {
                si_enum = si_enum.OrderByDescending(p => p.UPC).AsEnumerable();
            }

            foreach (ScoutItem si in si_enum)
            {
                int _OldIndex = this.IndexOf(si);
                int _NewIndex = si_enum.ToList().IndexOf(si);
                this.MoveItem(_OldIndex, _NewIndex);
            }
      }
}

... যেখানে স্কাউট আইটেমটি আমার সর্বজনীন ক্লাস। অনেক সহজ মনে হয়েছিল। যুক্ত সুবিধাসমূহ: এটি আসলে কাজ করে এবং বাইন্ডিংগুলির সাথে জগাখিচুড়ি করে না বা কোনও নতুন সংগ্রহ ইত্যাদি দেয় না etc.


1

ঠিক আছে, যেহেতু এক্সএএমএল এর সাথে কাজ করার জন্য আমার অবজারভেটরস্টার্ডলিস্ট পেতে সমস্যা হচ্ছিল, তাই আমি এগিয়ে গিয়ে সোর্টিংঅবার্সেবল কালেকশন তৈরি করেছি । এটি পর্যবেক্ষণযোগ্য সংগ্রহ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত, তাই এটি এক্সএএমএল এর সাথে কাজ করে এবং আমি ইউনিটটি এটি 98% কোড কভারেজ পর্যন্ত পরীক্ষা করেছি। আমি এটি আমার নিজস্ব অ্যাপ্লিকেশনগুলিতে ব্যবহার করেছি, তবে আমি প্রতিশ্রুতি দেব না যে এটি বাগ মুক্ত। অবদান নির্দ্বিধায়। এখানে নমুনা কোড ব্যবহার:

var collection = new SortingObservableCollection<MyViewModel, int>(Comparer<int>.Default, model => model.IntPropertyToSortOn);

collection.Add(new MyViewModel(3));
collection.Add(new MyViewModel(1));
collection.Add(new MyViewModel(2));
// At this point, the order is 1, 2, 3
collection[0].IntPropertyToSortOn = 4; // As long as IntPropertyToSortOn uses INotifyPropertyChanged, this will cause the collection to resort correctly

এটি একটি পিসিএল, সুতরাং এটি উইন্ডোজ স্টোর, উইন্ডোজ ফোন এবং .NET 4.5.1 এর সাথে কাজ করা উচিত।


4
আপনার সম্ভবত newএই সমস্ত পদ্ধতি ব্যবহার করা উচিত নয় , যদি কারও কাছে সাধারণভাবে টাইপ করা উদাহরণ থাকে তবে সেই পদ্ধতিগুলি কল করা হবে না। পরিবর্তে overrideপ্রতিটি ওভারিডেবল পদ্ধতি এবং সেগুলি প্রয়োজনীয় বা ফ্যালব্যাক হিসাবে পরিবর্তন করুন base.Method(...)। উদাহরণস্বরূপ, আপনাকে এমনকি উদ্বিগ্ন হওয়ারও দরকার নেই .Addকারণ এটি অভ্যন্তরীণভাবে ব্যবহার করে .InsertItem, তাই যদি .InsertItemওভাররাইড এবং সমন্বয় করা হয় তবে অর্ডারে কোনও গোলমাল .Addহবে না।
এইচবি

1

ওসি এক্সটেনশানগুলির সাথে এটিই করি:

    /// <summary>
    /// Synches the collection items to the target collection items.
    /// This does not observe sort order.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="source">The items.</param>
    /// <param name="updatedCollection">The updated collection.</param>
    public static void SynchCollection<T>(this IList<T> source, IEnumerable<T> updatedCollection)
    {
        // Evaluate
        if (updatedCollection == null) return;

        // Make a list
        var collectionArray = updatedCollection.ToArray();

        // Remove items from FilteredViewItems not in list
        source.RemoveRange(source.Except(collectionArray));

        // Add items not in FilteredViewItems that are in list
        source.AddRange(collectionArray.Except(source));
    }

    /// <summary>
    /// Synches the collection items to the target collection items.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="source">The source.</param>
    /// <param name="updatedCollection">The updated collection.</param>
    /// <param name="canSort">if set to <c>true</c> [can sort].</param>
    public static void SynchCollection<T>(this ObservableCollection<T> source,
        IList<T> updatedCollection, bool canSort = false)
    {
        // Synch collection
        SynchCollection(source, updatedCollection.AsEnumerable());

        // Sort collection
        if (!canSort) return;

        // Update indexes as needed
        for (var i = 0; i < updatedCollection.Count; i++)
        {
            // Index of new location
            var index = source.IndexOf(updatedCollection[i]);
            if (index == i) continue;

            // Move item to new index if it has changed.
            source.Move(index, i);
        }
    }

1

এটি আমার পক্ষে কাজ করেছিল, এটি অনেক আগে খুঁজে পেয়েছিল কোথাও।

// SortableObservableCollection
public class SortableObservableCollection<T> : ObservableCollection<T>
    {
        public SortableObservableCollection(List<T> list)
            : base(list)
        {
        }

        public SortableObservableCollection()
        {
        }

        public void Sort<TKey>(Func<T, TKey> keySelector, System.ComponentModel.ListSortDirection direction)
        {
            switch (direction)
            {
                case System.ComponentModel.ListSortDirection.Ascending:
                    {
                        ApplySort(Items.OrderBy(keySelector));
                        break;
                    }
                case System.ComponentModel.ListSortDirection.Descending:
                    {
                        ApplySort(Items.OrderByDescending(keySelector));
                        break;
                    }
            }
        }

        public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
        {
            ApplySort(Items.OrderBy(keySelector, comparer));
        }

        private void ApplySort(IEnumerable<T> sortedItems)
        {
            var sortedItemsList = sortedItems.ToList();

            foreach (var item in sortedItemsList)
            {
                Move(IndexOf(item), sortedItemsList.IndexOf(item));
            }
        }
    }

ব্যবহার:

MySortableCollection.Sort(x => x, System.ComponentModel.ListSortDirection.Ascending);

0

আমার একমাত্র নয়, একাধিক জিনিস বাছাই করতে সক্ষম হওয়া দরকার। এই উত্তরটি অন্য কয়েকটি উত্তরের উপর ভিত্তি করে তবে এটি আরও জটিল বাছাইয়ের অনুমতি দেয়।

static class Extensions
{
    public static void Sort<T, TKey>(this ObservableCollection<T> collection, Func<ObservableCollection<T>, TKey> sort)
    {
        var sorted = (sort.Invoke(collection) as IOrderedEnumerable<T>).ToArray();
        for (int i = 0; i < sorted.Count(); i++)
            collection.Move(collection.IndexOf(sorted[i]), i);
    }
}

আপনি যখন এটি ব্যবহার করেন, তখন অর্ডারবাই / থটারবি কলগুলির একটি সিরিজটি পাস করুন। এটার মত:

Children.Sort(col => col.OrderByDescending(xx => xx.ItemType == "drive")
                    .ThenByDescending(xx => xx.ItemType == "folder")
                    .ThenBy(xx => xx.Path));

0

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

নির্বিশেষে, সরান / সন্নিবেশ করানোর পরিবর্তে একটি সরানো ব্যবহার করা যেতে পারে, তবে এটি পারফরম্যান্স ফিক্স নিয়ে কিছু সমস্যা সৃষ্টি করে।

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

একটি একক পদক্ষেপের মধ্যে অবস্থানগুলির মধ্যে উপাদানগুলির সূচিগুলি স্থানান্তরিত হয়, যা সূচিপত্র অভিধানটি অকার্যকর করে দেবে। অদলবদল বাস্তবায়নে দ্বিতীয় পদক্ষেপ যুক্ত করা লোকেশনগুলি পুনরুদ্ধার করে।

public static void Sort<TSource, TKey>(this ObservableCollection<TSource> collection, Func<TSource, TKey> keySelector)
{
    List<TSource> sorted = collection.OrderBy(keySelector).ToList();
    Dictionary<TSource, int> indexOf = new Dictionary<TSource, int>();

    for (int i = 0; i < sorted.Count; i++)
        indexOf[sorted[i]] = i;

    int idx = 0;
    while (idx < sorted.Count)
        if (!collection[idx].Equals(sorted[idx])) {
            int newIdx = indexOf[collection[idx]]; // where should current item go?
            collection.Move(newIdx, idx); // move whatever's there to current location
            collection.Move(idx + 1, newIdx); // move current item to proper location
        }
        else {
            idx++;
        }
}

-3
var collection = new ObservableCollection<int>();

collection.Add(7);
collection.Add(4);
collection.Add(12);
collection.Add(1);
collection.Add(20);

// ascending
collection = new ObservableCollection<int>(collection.OrderBy(a => a));

// descending
collection = new ObservableCollection<int>(collection.OrderByDescending(a => a));

ওহ আমি এটি পেয়েছি ... গিয়াত সবচেয়ে নিম্নচরিত উত্তরটির কাছে অনুদান দিতে চেয়েছিল
নিলডাব্লু

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