tags:

views:

127

answers:

4

I'm trying to use linq where it makes my code readable - foreach loops generally being easy targets.

Yet there's one that seems simple but yet the linq form escapes me:

const byte EscapeByte = 0x5C;

List<byte> result = new List<byte>();
foreach (var v in values)
{
    if (v.Escaped)
    {
        result.Add(EscapeByte);
    }
    result.Add(v.DataByte);
}
return result.ToArray();

Which probably means it's best left alone.. yet I am curious if a veteran could linq it in a readable way?

A: 
return values.Select(v => v.Escaped ? EscapeByte : v.DataByte).ToArray();
Ruben
No, that's not equivalent. In the case Escaped is true two bytes need to be added to the result collection: `EscapeByte` **and** `DataByte`. In your case you are adding only `EscapeByte`.
Darin Dimitrov
ah, you are right, hm, that changes things...See Tim Robinsons answer for the correct solution to the question
Ruben
+6  A: 
return values.SelectMany(v => v.Escaped ? new[] { EscapeByte, v.DataByte } : new[] { v.DataByte }).ToArray();

Or:

return (from v in values
        from r in v.Escaped ? new[] { EscapeByte, v.DataByte } : new[] { v.DataByte }
        select r).ToArray()
Tim Robinson
+1, `SelectMany` needs to be used.
Darin Dimitrov
More readable? You're having a laugh.
spender
I prefer this - it emphasises the shape of the data returned, rather than the process used to build it. It also highlights the fact that either one or two bytes is returned per value; at first, I read it the same way that @Ruben did.
Tim Robinson
Well it's nice to see there is a linq solution. I think I'm going to side with spender though.. but accepting solution as I doubt there's cleaner linq.Edit: actually I've changed my mind, I'm going with linq as you're right - it would be misunderstood less. Regards.
Mania
Money well spent on the Resharper licence?
+3  A: 

While the above answers may be correct and show understanding of LINQ I would argue that none of them makes the code more readable. The functional approach is not always better.

Functional approach is best when the data is not mutated because this is how mathematical functions work. This is why LINQ can select but not insert or update. Your code inserts and probably this is why it does not look good when LINQ-ified. Of course you may find the LINQ code more readable as perception of readability varies from person to person.

Stilgar
A: 

Here you go - an alternative solution :)

    return values.Aggregate(new List<byte>(), (agg,v) =>
        {
            if(v.Escaped) agg.Add(EscapedByte);
            agg.Add(v.DataByte);
            return agg;
        }, agg => agg.ToArray());
Moberg