tags:

views:

142

answers:

3

I found this code snippet on a different post that I don't quite understand and would appriciate someone explaining.

private bool[] GetPageNumbersToLink(IPagedResult result)
{
   if (result.TotalPages <= 9)
      return new bool[result.TotalPages + 1].Select(b => true).ToArray();

   ...

http://stackoverflow.com/questions/136836/c-array-initialization-with-non-default-value

My take on this:

new bool[result.TotalPages + 1]

this creates an array of bools with length equal to that of the totalpages, the default value being false on all of them.

.Select(b => true)

this uses a linq query to return only the items that are true, i.e. none of them

.ToArray();

linq returns IEnumerable or something, so it needs to go back to a new array, of length 0 as none were selected in the first place.

I think that's what it's doing, but it doesn't make any sense.

+8  A: 

(EDIT: Oops, misread the post (unless it was edited without me noticing).)

No, that's not what it's doing. The result is effectively:

Enumerable.Repeat(true, result.TotalPages + 1).ToArray();

The Select call doesn't depend on the value that it's selecting at all - it's just returning true whatever the input is. Select doesn't perform filtering, just projection.

In other words:

// Array filled with (result.TotalPages + 1) x false
new bool[result.TotalPages + 1]

// Sequence of length (result.TotalPages + 1) x true
.Select(b => true)

// Array filled with (result.TotalPages + 1) x true
.ToArray();

Anyway it's inefficient. It's occasionally unfortunate that .NET doesn't provide something like:

public static T[] CreateFilledArray(T value, int size)
{
    T[] ret = new T[size];
    for (int i=0; i < size; i++)
    {
        ret[i] = value;
    }
    return ret;
}
Jon Skeet
The first line of this answer is a bit misleading... it's not actually doing what the OP describes. Select isn't performing any type of filter, it's returning true for each item in the array.
spoon16
@spoon16: Yup, hence my edits shortly before your comment :)
Jon Skeet
+5  A: 

.Select(b => true)

this uses a linq query to return only the items that are true, i.e. none of them

No, it means that for each item, it returns true. It doesn't do any test on the value of the array item

This code just creates an array with all items set to true

I prefer this form (no intermediate array) :

return new Enumerable.Range(0,result.TotalPages).Select(b => true).ToArray();
Thomas Levesque
`Enumerable.Repeat` is a more descriptive way of doing this, IMO.
Jon Skeet
yes you're right, I had forgotten about the `Repeat` method...
Thomas Levesque
+2  A: 

I believe the .Select(b => true) part returns "true" for every element in the array, so you actually get IEnumerable with result.TotalPages + 1 items and then it's converted to an array.

Filip Navara