views:

293

answers:

2

How to implement IComparable to sort numerical and non-numerical string.

Firstly, I want to get the Min and Max value in the "list".

It is asking me to implement ICompareable. " At least one object must implement IComparable"

Can anyone help me? Here is my code:

        // setup
        string filePath1 = Directory.GetCurrentDirectory().ToLower().Replace(@"\bin\debug", string.Empty)
            + @"\SampleData\products.xml";

        // load XML
        var xdoc1 = XElement.Load(filePath1);


        //list
        var elements = xdoc1.Descendants("ProductName").OrderBy(x => x.Value);

        //output
        Console.WriteLine("Min- " + elements.Min().Value);
        Console.WriteLine("Max- " + elements.Max().Value);


Here is my XML file:

<Products>
  <ProductName>9954</ProductName>
  <ProductName>987</ProductName>
  <ProductName>197</ProductName>
  <ProductName>56</ProductName>
  <ProductName>rr45</ProductName>
  <ProductName>ad4</ProductName>
  <ProductName>7</ProductName>
  <ProductName>69dd</ProductName>
  <ProductName>69</ProductName>
  <ProductName>197abc</ProductName>
</Products>
+1  A: 

You're trying to get the Min() and Max() elements To be able to call Min() on it, XElement should implement IComparable. Since it does not, you can't directly call Min on a Element collection.

Why don't you try to sort your elements by value and take the first and last?

var ordered = elements.OrderBy(e => e.Value).ToList();
var min = ordered.First().Value;
var max = ordered.Last().Value;
Yann Schwartz
Thanks for your helps, but I want to know how to do this with elements.OrderBy(e => e.Value).Min().Do you know how to implement IComparable interface. Thanks Yann.
Daoming Yang
You can't since element does not implement IComparable and Min expects an IComparable.
Yann Schwartz
Or you can do elements.OrderBy(e => e.Value).Select(e => e.Value).Min() but you won't get the Element, only the value.
Yann Schwartz
Sorry, elements.Select(e => e.Value).Min() is better.
Yann Schwartz
A: 

It is because you are asking for the minimum and maximum XElement object and the framework doesn't know how to compare XElements as it doesn't implement IComparable. var elements really evaluates to IEnumerable<XElement> elements.

Also note that your code is not very efficient as you are first sorting then looping through the list twice more, once for Min and once for Max.

Yann's solution is both more efficient and will work:

var ordered = elements.OrderBy(e => e.Value).ToList();      
var min = ordered.First().Value;      
var max = ordered.Last().Value;
Iain
Thanks Lain, I notice that. hoho...
Daoming Yang