score:2
I understand that the same string[] that comes as an argument is refilled with elements and returned
I'll address this briefly, because it's not the question you're asking. This isn't true - no refilling of anything occurs. The original array is unaltered and a Where is a loop that runs over the array and selectively emits items from it when the test presented to it evaluates to true for that item. The way it does this is via a special construct called a yield return
which is a way of allowing code to return from a method and then re-enter it and carry on from where it left off before, rather than starting all over again from the beginning of the method. There is only ever one array, and the looping/testing is not performed unless you start reading from the set of strings produced by the Where. If you want to know more about that, drop a comment.
Moving on..
Does linq know that a variable with a singular name is an element of a plural name group, here “names”?
No; the IDE knows the variable name
because that's what you chose to call it just after the Where(
Perhaps it would help to link it to something you already know. It would be perfectly acceptable to write this code:
public static class Kata {
public static IEnumerable<string> FriendOrFoe (string[] names) {
return names.Where(IsNameOfLengthFour);
}
static bool IsNameOfLengthFour(string name){
return name.Length == 4;
}
}
Where demands some method be supplied that takes a string and returns a boolean. It demands that the input be a string because it's being called on names
which is an array of string. If it were ints in the array, the method passed to Where would have to take an int
In C# there's often a push to make things more compact, so to get rid of all that wordiness above, we have a much more compact form of writing method bodies. Let's reduce our wordy version:
static bool IsNameOfLengthFour(string name){
return name.Length == 4;
}
We can chuck out the return type, because we can guess that from the type being returned. We can get rid of static too, and just assume static if we're calling it from inside another static, or not if we're not. We can ditch the input type too, because we can guess that from the type going in.
IsNameOfLengthFour(name){
return name.Length == 4;
}
If we have a special syntx that is only one line and must be a value that is auto returned, we can get rid of the return
, and the {}
because it's only one line, so we don't need to fence off multiple statements:
IsNameOfLengthFour(name) => name.Length == 4
Now, we don't actually need a method name any more either if we're going to use this in some place where a name is irrelevant, and we really don't need ()
for a single argument either:
name => name.Length == 4
And that's enough of an expression for the compiler to be able to form a method out of it, and plumb it into something that expects a method taking a string and returning a boolean. We've thrown away all the fluff of a method that we humans like (names and identifiers) and given the compiler just the raw nuts and bolts it needs - the logic of the method. The compiler will recreate the rest of the fluff when it wires it all together for us; we won't ever be able to call this mini-method from elsewhere in our code but we don't care. We got what we wanted, which is a nice compact way of expressing the logic:
Where(n => n.Length==4);
You did a good job, calling the argument to this mini-method something sensible. I see x
used a lot and it gets really confusing when what X is changes.. For example:
names
.Where(name => ...)
.GroupBy(name => ...)
.Select(g => g.First())
.Where(name => ...)
Where
works on your array of names so calling the argument to the delegate name
or n
is a good idea. Where will filter it down but ultimately it still emits a set of strings that are names, so it's still a good idea to call it name
on the way into a GroupBy.. But a GroupBy produces a set of IGrouping, not a set of string so the thing coming our of a GroupBy is no longer a name.. In the next Select I call it g
to reflect that it's a grouping, not a name, but I then take the first item in the grouping which is, actually, a name.. So in the final Where I go back to calling the input argument name
to reflect what it's back to being..
When LINQ statements get much more complicated, it really helps to name these arguments well
Note: in this answer I've used words like "list" or "set" and I mean those in the general English sense that an "array is a list of ..", not a specifically C# List<xxx>
or HashSet<xxx>
sense. If you see lowercase words that align with C# types, they are not intended to refer to that specific type
score:0
I understand that the same
string[]
that comes as an argument is refilled with elements and returned.
No, absolutely not. A new sequence of strings is returned based on the input array. The input array is not modified or changed in any way.
But how does the program know that each element of the array is called “name”, as it’s never mentioned before?
name
is a parameter to an anonymous function. The name
parameter is a string based on context. This could be x
or ASDASDASD
or whatever you want, but here we use name
since we have, on each call, one "name" from names
.
Thus,
names
is an array of strings passed into the function- the
.Where
returns a newIEnumerable<string>
from the current array based on a predicate function (e.g. returns true for a match, false to omit) - The predicate
name => name.Length == 4
takes a string and returns true if the string is length 4 - The return from the function is the strings from
names
that are exactly 4 characters in length
Source: stackoverflow.com
Related Query
- How does Linq know the name of an element?
- How does linq actually execute the code to retrieve data from the data source?
- How to query XML with the same element and attribute name using linq
- How does the following LINQ statement work?
- How does LINQPad reference other classes, e.g. Books in the LINQ in Action samples
- Linq to SQL: How do I stop the auto generated object name from being renamed?
- LINQ to XML: How to select the next element
- How does Linq work (behind the scenes)?
- How does the LINQ RefreshMode work?
- How does linq Last() determine the last item?
- How does a LINQ expression know that Where() comes before Select()?
- Does this LINQ code perform multiple lookups on the original data?
- How to understand the following C# linq code of implementing the algorithm to return all combinations of k elements from n
- How to get all elements except the n'th element in a List using Linq
- how does one compare the date part of a nullable datetime in a linq / lambda query?
- How to avoid "The name 'ConfigurationManager' does not exist in the current context" error?
- Linq OrderBy does not sort a List<T>. How do I sort the list?
- How does this linq code that splits a sequence work?
- Does anyone know how to reproduce an NVL() function in linq
- Does LINQ know how to optimize "queries"?
- How to find the index of next matching element in list using LINQ
- I need a LINQ expression to find an XElement where the element name and attributes match an input node
- Refactor Linq code and "LINQ to Entities does not recognize the method"
- How does OrderBy in LINQ work (behind the scenes)?
- How can I write the following code more elegantly using LINQ query syntax?
- How do I use LINQ to find 5 elements in a row that match one predicate, but where the sixth element doesn't?
- How to get the value of an XML element using Linq even when empty
- How to code the partial extensions that Linq to SQL autogenerates?
- How to apply a function to every element in a list using Linq in C# like the method reduce() in python?
- How does the CLR interpret the following LINQ query
More Query from same tag
- MVC Linq for multiple selects that allow multiple selections
- DB design strategy in Visual Studio
- Extract filtered list from large list
- Cast problem with LINQ
- LINQ Query across Associations
- LINQ compare string and DB column type 'text'
- LINQ Filter a Table with one large array
- How to use objects instead of anonymous Types
- Xamarin Forms - how to select resource in C# from MergedDictionaries
- LINQ conditional aggregation based on next elements' values
- C# Count removed nodes
- C# Is it possible to check if any specific digit is present in an ID?
- Compiled LINQ queries - NHibernate
- Optimizing a value based search algorithm with LINQ
- Object Oriented Model on top of LINQ to SQL
- ModelState is Invalid for Drop Down List
- LINQ - Join only one attribute with whole schema onf another entity
- Object functions fail within LINQ to Entities Expressions
- find missing column name and row no of datacolum in linq
- EF LINQ include nested entities
- LINQ, simplifying expression - take while sum of taken does not exceed given value
- Filtering an MVC SelectList from DB
- Why does this LINQ left join statement compile down to an SQL statement with a sub-query in EF 6?
- LINQ or REGEX to extract certain text from a string
- Adding item index number in Linq
- How to convert database results to Dictionary<int, List<decimal>>
- Querying a Array with list of anonymous Object
- Linq to Object combine 2 arrays in one as one to many
- How to get PEX to automatically generate inputs for code involving LINQ
- Linq lambda for searching a List within a List, finding a match, then deleting it from the list