0

How to filter a list such that filtering order remains intact in the output.

void Main()
{
    var states = new List<State>() { new State("CA", "California"), 
                                    new State("NY", "New York"), 
                                    new State("AL", "Alabama"),
                                    new State("NV", "Nevada")};
    var myOrder = new List<string>() {"AL", "NY"};

    var result = states.Where(s => myOrder.Exists(c => string.Equals(c, s.Code, StringComparison.OrdinalIgnoreCase)));
    foreach(var res in result)
    {
        Console.WriteLine(res.Code);
    }
    //this outputs - NY AL
}

public class State
{
    public string Code;
    public string Name;
    public State(string code, string name)
    {
        Code = code;
        Name = name;
    }
}

I need the output in the same order as given in myOrder list (expected output - AL NY).

DivideByzero
  • 474
  • 4
  • 15

2 Answers2

3

If I correctly understand what you want, a join would do that:

static void Main()
{
    //below is a database call, for sake of code simplicity, I have hardcoded few data samples.
    var states = new List<State>() { 
            new State("CA", "California"),
            new State("NY", "New York"),
            new State("AL", "Alabama"),
            new State("NV", "Nevada")
        };

    var myOrder = new List<string>() { "AL", "DE", "NY", "TX" };

    //  Join myOrder...
    var result = myOrder.Join(
        //  to states...
        states,
        //  ...on the whole myOrder item...
        o => o, 
        //  ...equals the Code field of the State
        s => s.Code,
        //  And the result of the join is just the State
        (o, s) => s);

    //  this outputs - AL NY 

    foreach (var res in result)
    {
        Console.WriteLine(res.Code);
    }
}

The easiest way to use the ordering from myOrder is just start there and don't change it. There are a number of ways to do this, but that'll work.

1

Add a condition to OrderBy correctly:

.OrderBy(s => myOrder.IndexOf(s.Code));

Your condition becomes:

var result = states
    .Where(s => myOrder.Exists(c => string.Equals(c, s.Code, StringComparison.OrdinalIgnoreCase)))
    .OrderBy(s => myOrder.IndexOf(s.Code));

Dotnet Fiddle Demo

degant
  • 4,861
  • 1
  • 17
  • 29