2

I have a list of MyClass and one of its properties is Position. Initially, the positions could be like this:

2,-3,1,3,4,5,-2,-1,

Using the Sort (NOT .OrderBy) method, I need a lambda expression that will result in the above numbers being ordered from lowest positive number and then from lowest negative number, so the output would be this:

1,2,3,4,5,-1,-2,-3

I'm new to lambda expressions, I got this far: myList.Sort((x, y) => x.Position.CompareTo(y.Position)) but it doesn't quite do what I want.

Cheers!

5 Answers 5

4

When x.Position and y.Position are both positive or both negative, you can order them by their absolute value. Otherwise, use the inverted value of CompareTo function

myList.Sort((x,y) => x.Position > 0 && y.Position > 0 || x.Position < 0 && y.Position < 0 ? 
                      Math.Abs(x.Position).CompareTo(Math.Abs(y.Position)) :
                      -x.Position.CompareTo(y.Position));
Sign up to request clarification or add additional context in comments.

1 Comment

-x.CompareTo should be -x.Position.CompareTo. Once I made that change, it worked PERFECTLY! Thank you!
2
static int Cmp(int x, int y)
{
    if (x > 0 && y < 0)
    {
        return -1;
    }

    if (x < 0 && y > 0)
    {
        return 1;
    }

    if (x < 0 && y < 0)
    {
        return y.CompareTo(x);
    }

    return x.CompareTo(y);
}
//---
List<int> list = new List<int> { 2, -3, 1, 3, 4, 5, -2, -1 };
list.Sort(Cmp);

Comments

2

You need to implement your own custom IComparable to your MyClass and implement CompareTo. More information can be found here. Here's a direct sample without using IComparable.

using System;
using System.Linq;
using System.Collections.Generic;
public class Test
{
    public static void Main()
    {
        var myList = new List<int>() { 2,-3,1,3,4,5,-2,-1,};
        myList.Sort(Compare);
        foreach(var item in myList){
            Console.WriteLine(item);
        }
    }

    static int Compare(int x, int y)
    {
     if (x > 0 && y < 0)
     {
        return -1;
     }

     if (x < 0 && y > 0)
     {
        return 1;
     }

     if (x < 0 && y < 0)
     {
        return y.CompareTo(x);
     }
     return x.CompareTo(y);
    }
}

For objects A, B and C, the following must be true: A.CompareTo(A) must return zero. If A.CompareTo(B) returns zero, then B.CompareTo(A) must return zero. If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero, then A.CompareTo(C) must return zero. If A.CompareTo(B) returns a value other than zero, then B.CompareTo(A) must return a value of the opposite sign. If A.CompareTo(B) returns a value x not equal to zero, and B.CompareTo(C) returns a value y of the same sign as x, then A.CompareTo(C) must return a value of the same sign as x and y. Notes to Callers Use the CompareTo method to determine the ordering of instances of a class.

Comments

0
 class ListOperations
{
    public static void Main(string[] args)
    {
        List<Book> books = new List<Book>
       {
           new Book { Name="book1",ISBN= 554654,Category= "Mathematics",Price=12.45,Index=1},
           new Book { Name="book2",ISBN= 454654, Category="English", Price=-6.45, Index=3},
           new Book {Name="book3",ISBN= 754654, Category="English", Price=7.45, Index=4 },
           new Book { Name = "book4", ISBN = 854654,Category= "History", Price=8.45,Index= 5 },
           new Book { Name = "book5", ISBN = 154654, Category="Mathematics", Price=17.45, Index=2 },
           new Book { Name = "book6", ISBN = 354654, Category="History", Price=-15.45, Index=6 },
           new Book { Name = "book7", ISBN = 354653, Category="History", Price=0, Index=6 }
        };
        books.Sort((x, y) =>( x.Price > 0 && y.Price > 0 || x.Price < 0 && y.Price < 0 )? Math.Abs(x.Price).CompareTo(Math.Abs(y.Price)) : -x.Price.CompareTo(y.Price));
    }

    class Book
    {
        public string Name { get; set; }
        public int ISBN { get; set; }
        public string Category { get; set; }
        public double Price { get; set; }
        public double Index { get; set; }
        public int RowNum { get; set; }
    }
}

Comments

-2

This code works for your case.

var values = new[] {2,-3,1,3,4,5,-2,-1};
var solution = values.GroupBy(i => i > 0)
    .SelectMany(g => g.Key? g.OrderBy(c=>c) : g.OrderByDescending(c=>c))
    .ToArray();

Working sample attached here.

5 Comments

Your code won't work. It will produce the output 2 -3 1 3 4 5 -2
@lll Can you check sample that I have attached ?
I did. it doesn't compile.
@lll What do you mean it doesn't compile? it is working. I don't see it is fair to down vote without even verifying the code and links.
I did verify the code and link. Also, it was broken so you must have fixed it and I didn't down vote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.