2013-10-07 26 views
-4

我似乎无法得到我的头。
我有以下几点:使用数组排序列表<object>

private String[] PREFERED = new String[] { "37", "22", "18" }; 

    private List<Stream> library; 

    public class Stream 
    { 
     public String ID { get; set; } 
     public String URL { get; set; } 
     public String Description { get; set; } 
     public String Type { get; set; } 
    } 

而且我想用PREFERED字符串数组排序的List<Stream>命名为library,使我的结果将是library用下面的命令:352218,...

library = library.OrderBy(o => Array.IndexOf(PREFERED, o.ID)).ToList(); 

但我没有得到预期的结果...

JSON

[{"ID":"44","URL":null,"Description":".webm (854x480)","Type":".webm"}, 
{"ID":"35","URL":null,"Description":".3gp (854x480)","Type":".3gp"}, 
{"ID":"43","URL":null,"Description":".webm (640x360)","Type":".webm"}, 
{"ID":"34","URL":null,"Description":".flv (640x360)","Type":".flv"}, 
{"ID":"18","URL":null,"Description":".mp4 (480x360)","Type":".mp4"}, 
{"ID":"5","URL":null,"Description":".flv (400x240)","Type":".flv"}, 
{"ID":"36","URL":null,"Description":".flv (400x240)","Type":".flv"}, 
{"ID":"17","URL":null,"Description":".3gp (176x144)","Type":".3gp"}] 
+2

你会得到什么结果? – Andrew

+6

第一个元素('37'和'35')的差异是否也存在于您的代码中? – Douglas

+2

我相信这应该工作给所有的ID保证存在,但是如果没有找到'IndexOf'返回减1,这会撞到一个不存在的ID到列表的前面。 –

回答

1

我想这样的作品即使所在PREFERED不包含ID的情况下s在library

var ranks = 
    PREFERED 
     .Select((x, n) => new { x, n }) 
     .ToLookup(xn => xn.x, xn => xn.n); 

library = 
    library 
     .OrderBy(l => 
      ranks[l.ID] 
       .DefaultIfEmpty(int.MaxValue) 
       .First()) 
     .ToList(); 

这里的解释是,按照他请求注释INT。

.Select((x, n) => new { x, n })将值序列投影到序列中的值及其索引序列中。

.ToLookup(xn => xn.x, xn => xn.n)将序列更改为类似字典的结构,该结构从所提供的任何密钥返回零个或多个值的列表,而不管该密钥是否在原始序列中。如果键不在原始序列中,则返回空值序列。

表达式​​获取library序列中的每个id并应用查找,返回值序列。表达式.DefaultIfEmpty(int.MaxValue)确保序列具有至少一个值,并且表达式.First()返回序列的第一个值。因此,这可确保library来源中的ever ID能够从PREFERED序列获得可能的匹配索引值,如果该ID不在PREFERED序列中,则可获得int.MaxValue

然后,按照返回的值排序并使用.ToList()重新创建列表是一件简单的事情。

+0

太棒了!这像一个魅力。而且很漂亮! ^^ – grmbl

+0

你能一步一步解释这个解决方案吗? – grmbl

+1

@grmbl - 我已根据您的要求添加了解释。 – Enigmativity

0

看起来好像你只是希望他们在基础上,ID场降序去,为什么不这样做

library = library.OrderByDescending(x => Int32.Parse(x.ID)).ToList(); 
+0

由于'“22”'大于'“18”'/根据名称,降序很可能是巧合 –

+0

@HenkHolterman我将字符串解析为一个int ... – James

+0

_parsing string to an int_ - very questionable for a string Id' field。 –

1

我试着按照Linqpad代码和它的工作了我:

void Main() 
{ 
String[] PREFERED = new String[] { "37", "22", "18" }; 
List<Stream> library = new List<Stream>() ; 
library.Add (new Stream() {ID ="22" }) ; 
library.Add (new Stream() {ID ="37" }) ; 
library.Add (new Stream() {ID ="18" }) ; 
library.Dump() ; 
library.OrderBy(o => Array.IndexOf(PREFERED, o.ID)).ToList().Dump() ; 

} 

public class Stream 
{ 
    public String ID { get; set; } 
    public String URL { get; set; } 
    public String Description { get; set; } 
    public String Type { get; set; } 
} 
+0

在Linqpad(我刚刚做过)试试这个: 'void main() { String [] PREFERED = new String [] {“18”,“22”,“37”}; 列表库=新列表(); library.Add(new Stream(){ID =“22”}); //library.Add(new Stream(){ID =“37”}); library.Add(new Stream(){ID =“18”}); library.Add(new Stream(){ID =“33”}); library.Dump(); library.OrderBy(o => Array.IndexOf(PREFERED,o.ID))。ToList()。转储(); } public class Stream { public String ID {get;组; } public String URL {get;组; } public String Description {get;组; } public String Type {get;组; } }' – grmbl

+2

将包含ID = 33的元素置于列表的顶部。这个ID不存在于PREFERED – User1551892