LINQ Orderby Max键之间的距离

时间:2016-03-09 16:57:40

标签: c# linq sorting

我有一个系统将大量未排序的对象列表中的数据插入存储系统。存储系统根据对象的TypeKey为插入分配处理(注意 - 存在提供唯一性的辅助键)。有多个具有相同TypeKey的对象,但这不会在对象列表中平均分配。如果我按顺序插入太多相同的键,则进程可能会受到限制,因此不执行此操作会有很大的优势。

我的目标是获取未排序的对象列表,并按照最大化(或最佳尝试)具有相同TypeKey的对象之间距离的顺序将它们添加到线程安全队列中。

注意 - 我在.NET Framework 4.6上的C#中这样做。如果我可以避免它,我想避免许多外部依赖。

示例:

    class DataPack
    {
        public string TypeKey {get; set;} 
        public string UniqueKey {get; set;}
        public object DataPackage {get; set;}
    }

伪代码

List<DataPack> rawList = {lotsa data, ~80k datapacks spread across 3000+ keys}
List<DataPack> maxDistSortedList = rawList.OrderByMaxDist();  //Not real function
ConcurrentQueue<DataPack> cq = new ConcurrentQueue<DataPack>();

ForEach (DataPack item in maxDistSortedList)
   {
      cq.Enqueue(item);
   }

然后,我将从并行进程内的ConcurrentQueue中提取数据,以将数据发送到存储系统。

此时我正在集思广益创建排序算法的想法,但我似乎正在为一个高效的过程打一堵墙,不需要通过多个循环进行大量的迭代。

1 个答案:

答案 0 :(得分:1)

我可能错过了一些东西,但想法是先用Typekey对它们进行分组,然后使用带有两个参数的select方法为typekey组中的每个条目分配一个索引,然后按该索引排序。然后它将获取TypeKey-1的第一个条目,TypeKey-2的第一个条目,TyperKey-n的第一个条目,然后重新开始使用TypeKey-1的第二个,等等。

var newList=rawList
    .GroupBy(x=>x.TypeKey)
    .Select(x=>x.Select((y,i)=>new {y=y,i=i}))
    .SelectMany(x=>x)
    .OrderBy(x=>x.i)
    .Select(x=>x.y);

测试代码:

void Main()
{
    var massdata=new List<DataPack>(){
        new DataPack {TypeKey="0001",UniqueKey="0000",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0001",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0002",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0003",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0004",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0005",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0006",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0007",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0008",DataPackage="yes"},
        new DataPack {TypeKey="0001",UniqueKey="0009",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0010",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0011",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0012",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0013",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0014",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0015",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0016",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0017",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0018",DataPackage="yes"},
        new DataPack {TypeKey="0002",UniqueKey="0019",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0020",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0021",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0022",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0023",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0024",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0025",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0026",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0027",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0028",DataPackage="yes"},
        new DataPack {TypeKey="0003",UniqueKey="0029",DataPackage="yes"},
    };
    var result=massdata
    .GroupBy(x=>x.TypeKey)
    .Select(x=>x.Select((y,i)=>new {y=y,i=i}))
    .SelectMany(x=>x)
    .OrderBy(x=>x.i)
    .Select(x=>x.y);
    result.Dump();
}

// Define other methods and classes here
class DataPack
{
   public string TypeKey {get; set;} 
   public string UniqueKey {get; set;}
   public object DataPackage {get; set;}
}

结果:

enter image description here

现在,如果有一个类型键的条目多于其他类型键,那么最后会出现问题,因为它们都是那个类型键,但这是一个快速的解决方案,不一定是最好的解决方案。