Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

c# - At least one object must implement IComparable calling OrderBy()

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; }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...