SamFisher83
SamFisher83

Reputation: 4015

using linq to find consecutive elements in an array

I am reading some data.

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

I want to be able to locate the index where the magic number for gzip (0x1f8b) starts. Is there a way to do it via linq?

Upvotes: 1

Views: 970

Answers (2)

Phil
Phil

Reputation: 43021

I'm not sure if this is very efficient, but

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);

Which results in the index of 0x1f or null if it's not found.

Or

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);
}

Upvotes: 2

BrokenGlass
BrokenGlass

Reputation: 161002

Kinda cheating but if you can use the index:

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

I second the comment though - a simple loop is much clearer, readable and more efficient in this case.

Upvotes: 0

Related Questions