2013-10-07 23 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