2012-03-15 47 views
1

我正在讀取一些數據。使用linq查找數組中的連續元素

byte[] data = inHandle.ReadBytes(int.MaxValue); 

我希望能夠找到gzip(0x1f8b)的幻數開始處的索引。有沒有辦法通過linq做到這一點?

+4

不意味着居高臨下,但爲什麼使用LINQ而不是標準的數組方法..'Array.IndexOf'? – 2012-03-15 21:18:52

+0

只是想知道它是否可以完成。我也可以使用for循環。 – SamFisher83 2012-03-15 21:22:10

回答

2

我不知道這是非常有效的,但

byte[] data = new byte[]{ 1, 2, 3, 4, 0x1f, 0x8b, 5, 6 }; 

var indexedData = data.Select ((element,index) => new {element, index}); 

int? magicIndex = 
    (from d1 in indexedData 
    from d2 in indexedData 
    where d1.index == d2.index-1 && d1.element == 0x1f && d2.element == 0x8b 
    select (int?)d1.index).SingleOrDefault(); 

Console.WriteLine(magicIndex); 

,如果它沒有找到導致0x1F的索引或空。

或者

var magicNo = data.Zip(data.Skip(1), 
    (first, second) => first*256 + second).Select ((d,i) => new {d, i}).FirstOrDefault (d => d.d==0x1f8b); 

if(magicNo != null) 
{ 
    Console.WriteLine(magicNo.i); 
} 
+0

+1爲第二個解決方案:) – 2012-03-15 22:03:08

0

還挺作弊,但如果你可以使用索引:

var idx = data.Select((b,index)=> new 
       { 
        IsGzipStart = b == 0x1f && data[index+1] == 0x8b, 
        Index = index 
       }).FirstOrDefault(x => x.IsGzipStart); 
Console.WriteLine(idx.Index); 

我第二次評論,但 - 一個簡單的循環更清晰,可讀性和更有效的在這種情況下。