MB34
MB34

Reputation: 4434

C# Reordering List<string> based on another List<string>

The answer here was a start Rearrange a list based on given order in c#

But, I want to order by a list of strings.

I updated my fiddle (https://dotnetfiddle.net/dWuh8l) to try this with no luck:

public class kw
{
    public string fkp_keyword { get; set; }
}

public static void Main()
{
    string url = "http://survey.scic.com/Survey/api/DocColumns";
    string parms = String.Concat(url, "/1158341");
    List<kw> kws;
    using (WebClient client = new WebClient())
    {
        client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        string result = client.DownloadString(parms);
        string unescapedJson = JsonConvert.DeserializeObject<string>(result);
        kws =  JsonConvert.DeserializeObject<List<kw>>(unescapedJson);
    }    

    var order = new List<string> { "FILENAME", "DOC_NAME", "PRINT_DATE", "EVENT_CODE", "CE_STATE", "DESIGNATION", "PROGRAM_CODE", "DISTRIBUTION", "COURSE NAME", "RECEIPT_DATE", "REC_RID" }; 

    var res = order.Select(i => kws.FindIndex(s => s.Equals(order.IndexOf((i))))).ToList();

    Console.WriteLine(res[1]);
}

Since I may have items that are not in the order list, where will they be placed in the new list res?

Upvotes: 1

Views: 1263

Answers (1)

konkked
konkked

Reputation: 3231

You can do select the index of the item, throw it into an anonymous object order by that and then select the string again :

    var res = kws
            .Select(a=>new{orderOf=order.IndexOf(a.fkp_keyword),val=a})
            .OrderBy(a=>a.orderOf)
            .Select(a=>a.val)
            .ToList();

If you have items that are not in the list you are ordering by then they will be put in the front, because IndexOf method would return -1.

You could easily filter them out too, just by using a where clause to check for -1 if you wanted

   var res = kws
            .Select(a=>new{orderOf=order.IndexOf(a.fkp_keyword),val=a})
            .OrderBy(a=>a.orderOf)
            .Where(a=>a.orderOf!=-1)
            .Select(a=>a.val)
            .ToList();

If you wanted to add them to the end of the list then you could break up the ones that are on the list and the ones that aren't and concat them rather than using a list.

    var temp = kws
            .Select(a=>new{orderOf=order.IndexOf(a.fkp_keyword),val=a})
            .OrderBy(a=>a.orderOf);

    var res = temp
                .Where(a=>a.orderOf != -1)
                .Select(a=>a.val)
                .Concat(
                     temp.Where(a=>a.orderOf==-1).Select(a=>a.val) 
                );

Upvotes: 3

Related Questions