Sort collection by another collection values

送分小仙女□ 提交于 2020-01-05 02:01:08

问题


I have List<SomeData> data;

public class SomeData
{
    public int Key { get; set;}
    public decimal Value { get; set;}
}

Also i have List<int> DataOrder;

I need to sort List<SomeData>data by Key, placing it in same order as List<int> DataOrder values.

Is there any common algorithms for that?

Example:

List<SomeData> data = new List<SomeData>();
data.Add(new SomeData{ Key = 10, Value = 14 })
data.Add(new SomeData{ Key = 25, Value = 22 })
data.Add(new SomeData{ Key = 567, Value = 3 })
data.Add(new SomeData{ Key = 57, Value = 300 })
data.Add(new SomeData{ Key = 17, Value = 200 })
data.Add(new SomeData{ Key = 343, Value = 42 })

List<int> DataOrder = new List<int>{1, 25, 700, 567, 343, 350, 10};

Result after sorting:

foreach(var element in data)
{
     Console.WriteLine(element.Key);
}

Out:

25
567
343
10
57
17

Edit: initial data array can have Key, that not contain in DataOrder Such value should be placed at the end of result collection in any order. Example changed to illustrate it.


回答1:


What about joining:

var mySortedList = (from i in DataOrder
            join d in data on i equals d.Key
            select new SomeData 
            { 
                Key = d.Key, 
                Value = d.Value 
            });

EDIT: To also add those values from data that do NOT share any key within the DataOrder-list you may simply add a Union to the result as follows:

var result = mySortedList.Union(data.Where(x => !DataOrder.Contains(x.Key)));



回答2:


Solved

public class SomeData
{
    public int Key { get; set; }
    public decimal Value { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<SomeData> orders = new List<SomeData>();

        orders.Add(new SomeData { Key = 10, Value = 14 });
        orders.Add(new SomeData { Key = 25, Value = 22 });
        orders.Add(new SomeData { Key = 567, Value = 3 });
        orders.Add(new SomeData { Key = 57, Value = 300 });
        orders.Add(new SomeData { Key = 17, Value = 200 });
        orders.Add(new SomeData { Key = 343, Value = 42 });

        List<int> ids = new List<int> { 1, 25, 700, 567, 343, 350, 10 };

        //get orders only from ids with order
        List<SomeData> existedOrders = (from order in orders
                                        join id in ids
                                             on new { onlyId = order.Key }
                                            equals new { onlyId = id }
                                        orderby ids.IndexOf(id)
                                        select order).ToList();

        //add others
        existedOrders.AddRange(orders.Except(existedOrders).ToList());

    }
}

//with @HimBromBeere solution you can reduce query

//get orders only from ids with order
List<SomeData> existedOrders = (from order in orders
                                join id in ids
                                     on order.Key equals id
                                orderby ids.IndexOf(id)
                                select order).ToList();



回答3:


int count = 0;
for(int i in DataOrder)
{
    var index = data.IndexOf(d => d.Key == i);
    swap(data[count], data[index]);
    count++;
}

and swap function is for swap places of items.



来源:https://stackoverflow.com/questions/31672401/sort-collection-by-another-collection-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!