Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to strip blocks out of an IEnumerable?

Tags:

c#

linq

I'm posting this more as a learning exercise than because I need to change the implementation away from an imperative loop. My question is how would one convert this loop to LINQ? Given an input IEnumerable of bytes which is considered to be in "blocks" of 8 bytes. The output IEnumerable should have any blocks which contain a 0 removed.

Rough Imperative implementation

    private static IEnumerable<byte> StripBlocksWithZeroes(IEnumerable<byte> input)
    {
        var stripped = new List<byte>();
        var inputArray = input.ToArray();
        for (int i = 0; i < inputArray.Length; i += 8)
        {
            if (inputArray[i + 0] != 0 &&
                inputArray[i + 1] != 0 &&
                inputArray[i + 2] != 0 &&
                inputArray[i + 3] != 0 &&
                inputArray[i + 4] != 0 &&
                inputArray[i + 5] != 0 &&
                inputArray[i + 6] != 0 &&
                inputArray[i + 7] != 0)
            {
                stripped.Add(inputArray[i + 0]);
                stripped.Add(inputArray[i + 1]);
                stripped.Add(inputArray[i + 2]);
                stripped.Add(inputArray[i + 3]);
                stripped.Add(inputArray[i + 4]);
                stripped.Add(inputArray[i + 5]);
                stripped.Add(inputArray[i + 6]);
                stripped.Add(inputArray[i + 7]);
            }
        }
        return stripped;
    }
like image 989
Felix Avatar asked Feb 02 '26 05:02

Felix


1 Answers

Off the top of my head:

inputArray.Select((item, index) => new {item, groupIndex = index / 8})
          .GroupBy(x => x.groupIndex)
          .Where(g => g.All(x => x.item != 0))
          //.Select(g => g.First().item)
          .SelectMany(g => g.Select(x => x.item))

A bit of explanation:

Tag each item with a groupIndex, taking advantage of integer division, so each contiguous group of 8 will have the same groupIndex.

Group by the group index, so now we have a sequence of sequences.

For each of the inner sequences, make sure it doesn't contain a zero.

Flatten the resulting sequence of sequences back to a single sequence.

like image 173
spender Avatar answered Feb 05 '26 07:02

spender



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!