At least one object must implement IComparable calling OrderBy()

41,596

Solution 1

To order a set of things, there must be a way to compare two things to determine which one is larger, or smaller or whether they are equal. Any c# type that implements the IComparable interface, provides the means to compare it versus another instance.

Your tags field is a list of strings. There is no standard way to compare two lists of strings in that manner. The type List<string> does not implement the IComparable interface, and thus cannot be used in a LINQ OrderBy expression.

If for example you wanted to order the articles by the number of tags, you could do that like this:

coll = coll.OrderBy(a => a.tags.Count).ToList();

because Count will return an integer and an integer is comparable.

If you wanted to get all unique tags in sorted order, you could do that like this:

var sortedUniqueTags = coll
    .SelectMany(a => a.Tags)
    .OrderBy(t => t)
    .Distinct()
    .ToList();

because a string is comparable.

If you really know how to compare two lists of strings, you could write your own custom comparer:

public class MyStringListComparer : IComparer<List<string>>
{
    // implementation
}

and use it like this:

var comparer = new MyStringListComparer();
coll = coll.OrderBy(a => a.tags, comparer).Distinct().ToList();

Solution 2

ArticleJSON does not implement IComparable while String does. The compiler does not know how to compare ArticleJSON for the OrderBy() you are calling. It works fine when you are using a list of string because of this.

Share:
41,596
Fly_federer
Author by

Fly_federer

Updated on April 15, 2020

Comments

  • Fly_federer
    Fly_federer about 4 years

    I already saw this question, but i didn't find my happiness with the answers...

    I'm trying to do that:

    var coll = JsonConvert.DeserializeObject<ObservableCollection<ArticleJSON>>(json);
    coll = coll.OrderBy(a => a.tags).Distinct().ToList();
    

    Throws an error:

    At least one object must implement IComparable.

    For the moment i didn't find the solution so i did that:

    List<string> categories = new List<string>();    
    var coll = JsonConvert.DeserializeObject<ObservableCollection<ArticleJSON>>(json);
    
    for (int i = 0; i < test.Count; ++i)
    {
        for (int j = 0; j < test[i].tags.Count; ++j)
        {
            _categories.Add(test[i].tags[j]);
        }
    }
    
    categories = _categories.Distinct().ToList();
    

    It works but i'm curious to know why the first one don't work.

    EDIT :

    My data come from a JSON :

                'tags': [ 
    
                                            'Pantoufle',
                                            'Patate'
                                         ]
                                },
                public List<string> tags { get; set; }
    
  • Fly_federer
    Fly_federer about 9 years
    Thank you for this answer !
  • Jim Balter
    Jim Balter over 5 years
    No. The OP is comparing tags, which are List<string>. Lists (as opposed to their contents) don't have a defined order.
  • Jenna Leaf
    Jenna Leaf about 5 years
    Mine doing this _objList = _objList.OrderBy(rr => new { rr.xa, rr.xb }).ToList(); would not work but it works when I separated them like .OrderBy(rr=>rr.xa).ThenBy(rr => rr.xb ).ToList(); Still don't know why the former does not work.