2

I need to sort an employee list based on predefined uniqueIds.

In simple words, consider a list of employee Ids 1 to 10 in random order.

I have a predefined rule that says order employee objects in 2, 8, 1, 4, 6 And if any employee UId is not in range [1,10] put them at the end of list...(any order).

I wrote following code using IComparer<Employee>.

public class Employee
    {
        public int UId { get; set; }
        public string Name { get; set; }        
    }

    class Comparision : IComparer<Employee>
    {
        List<int> referenceKeys = new List<int> { 2, 8, 1, 4, 6 };
        public int Compare(Employee thisOne, Employee otherOne)
        {
            var otherIndex = referenceKeys.IndexOf(otherOne.UId);
            var thisIndex = referenceKeys.IndexOf(thisOne.UId);
            if (thisIndex > otherIndex)
            {
                return 1;
            }
            else if (thisIndex < otherIndex)
            {
                return -1;
            }
            else
            {
                //if uid not found in reference list treat both employee obj as equal
                return 0;
            }
        }
    }
    class CustomSorting
    {
        public static 
        List<Employee> employees = new List<Employee>
        {
            new Employee{UId=1, Name="Ram"},
            new Employee{UId=2 , Name="Shyam"},
            new Employee{UId=3 , Name="Krishna"},
            new Employee{UId=4 , Name="Gopal"},
            new Employee{UId=5 , Name="Yadav"},
            new Employee{UId=6 , Name="Vishnu"},
            new Employee{UId=7 , Name="Hari"},
            new Employee{UId=8 , Name="Kanha"},
        };

        void sort()
        {
            employees.Sort(new Comparision());
        }

        static void Main()
        {
            new CustomSorting().sort();
        }
    }

I have been able to sort the list, with following result-

(5, 7, 3), 2, 8, 1, 4, 6 ==> 5, 7, 3 are not listed in reference key, so should appear in last, any order..

But items not found in my reference keys, are sorted first. I need to put them at the end.

For such a scenario, is IComparer, best way to go for ?

1 Answer 1

4

var otherIndex = referenceKeys.IndexOf(otherOne.UId); will return -1 if the item isn't found, which will be less than any found value.

You want all not found items to be greater than any found value, so just add:

if(otherIndex == -1) otherIndex = int.MaxValue;
if(thisIndex == -1) thisIndex = int.MaxValue;

On a side note, you can simplify the remainder of the method by just using:

return thisIndex.CompareTo(otherIndex);
Sign up to request clarification or add additional context in comments.

4 Comments

should that be = rather than ==
When item is not found.. otherIndex would be -1, but the return value would depend upon evaluation of var thisIndex = referenceKeys.IndexOf(thisOne.UId);.
Returning int.MaxValue in fact doesn't help, it mixes up the undesired Id. The produced output for sample run is.. (7) 2 8 (5) (3) 1 4 6. ...Items in the parenthesis should appear last.
Well, I ran this code and got: 2 8 1 4 6 3 5 7. You say, "Returning int.MaxValue", but you shouldn't be returning int.MaxValue, you should be setting each index to the max value. All you need to do is literally copy/paste the two lines of code that I have to your Compare method just after you declare the two index variables (and before the if statement). If you want, you can replace the if/else if/else block with the 3rd line of code I've provided.

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.