|
OriginalGriff wrote: I can't get my head round the Linq syntax, so I always use method chaining.
I tend to use both, depending on what I'm doing. For example, this:
var categoryRanks = (from gs in geekSkills
where (gs.ProfileId == profile.Id)
join s in skills on gs.SkillId equals s.Id
select new { Level = gs.Level, CategoryId = s.CategoryId } into gss
join c in categories on gss.CategoryId equals c.Id
select new { Level = gss.Level, Name = c.Name } into gssc
group gssc by new { gssc.Name, gssc.Level } into g
select new SkillLevelBySkillByCategory() {
SkillLevel = g.Key.Level,
SkillLevelCount = g.Count(x => x.Level == g.Key.Level),
Name = g.Key.Name });
seems more readable to me than method chaining, but I also do things like this:
T record = mappedRecords[typeof(T)].Cast<T>().Where(r => r.Row == row).Single();
because here, it flows better.
Marc
Marc
|
|
|
|
|
Same here, I never got the hang of it - never liked it to be honest, and always use C# method syntax.
|
|
|
|
|
Ah, you might like the LINQ to objects book[^] then, it is brilliant. (At least I think it is )
Tons of useful tips in it, and a very nice read as well.
|
|
|
|
|
Yeah, let is great.
Sometimes I convert a query from method syntax to query syntax just so I can use let
|
|
|
|
|
Hi Marc,
I first became aware of the 'Let and 'Into Linq operators through this 2011 CP article (which I down-voted for "lack of original content"): [^]. I have never used them because I have never invested the energy to learn to use the "fuller" query syntax (my bad).
Your comment makes me wonder what I am missing (other than motivation).
cheers, Bill
p.s. the Microsoft example of 'Let you cite imho goes to a lot trouble do this:
string[] strings =
{
"A penny saved is a penny earned.",
"The early bird catches the worm.",
"The pen is mightier than the sword."
};
string vowels = "aeiou";
List<string> vowelstartwords = String.Join(" ", strings)
.Split(' ')
.Distinct()
.Where(word => vowels.Contains(Char.ToLower(word[0])))
.ToList(); That example, taken as a programming challenge, interests me: it leaves me wondering if it could be significantly improved in terms of memory use and execution time, and if the Linq code using 'Let would, in fact, improve those usage parameters.
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
modified 8-Jun-16 14:41pm.
|
|
|
|
|
I'd be inclined to avoid joining the strings just to split them again.
I'd also be inclined to use an array of char , rather than searching a string - although I doubt it would make much difference.
You've also added a Distinct and a ToList which weren't in the original example.
char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
IEnumerable<string> vowelStartWords = strings
.SelectMany(sentence => sentence.Split(' '))
.Where(word => Array.IndexOf(vowels, char.ToLower(word[0])) != -1)
;
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I'm always delighted to have a chance to learn from your code !
I did add the call to 'Distinct with my first (and only) edit of the original post because I got to thinking that if you had a lot of 'if and 'else and 'and and 'is and 'or, etc., that would eliminate some duplicate calls.
edit ... my head spins as I consider the ways you can use Linq to "coalesce collections:" ''SelectMany, 'Aggregate, 'Join, etc.
thanks, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
Console.WriteLine(
string.Join(
"\n",
strings.SelectMany(sentence => sentence.Split(' '))
.Where(word => Array.IndexOf(vowels, char.ToLower(word[0])) != -1)
.Select(vowelWord => $"\"{vowelWord}\" starts with a vowel")))
;
|
|
|
|
|
Shame there's no foreach extension method:
public static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (action == null) throw new ArgumentNullException(nameof(action));
foreach (T item in source)
{
action(item);
}
}
}
Then you could do:
strings.SelectMany(sentence => sentence.Split(' '))
.Where(word => Array.IndexOf(vowels, char.ToLower(word[0])) != -1)
.Select(vowelWord => $"\"{vowelWord}\" starts with a vowel")
.ForEach(Console.WriteLine)
;
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Well, you could convert the IEnumerable to a List with ToList and call the ForEach method of the List<T> class. Should pretty much equal the foreach loop (as you need to evaluate the query anyways when looping)
|
|
|
|
|
|
I actually thought about a nasty Linq-with-side-effect version with something like
.Select(vowelWord => Console.WriteLine($"\"{vowelWord}\" starts with a vowel"))
but of course you can't, because Console.WriteLine() returns Void. No doubt it would be possible to force something like this, but that'd be silly; it's actually quite neat that C# protects us from such folly. For one thing, it won't evaluate until the IEnumerable is enumerated, so you don't really know when that is just from that line of code.
|
|
|
|
|
Marc, you probably know this by now, but let is just syntactic sugar for the Select method.
|
|
|
|
|
Haha, I have to say I dunno "how to replace let with extension method" so when I want to introduce a variable it's one case where I definitely use linq query syntax over chaining LINQ extension methods....
|
|
|
|
|
For a bit of background. LINQ facilitates functors and monads (concepts from functional programming). Simplified: functors are types that 'map' (Select), monads are types that 'bind' (SelectMany).
When you do 'from x in y' you're lifting the value out of the monad (get the value wrapped up *in* the monad), doing an operation on it, and then wrapping it back up in the monad. The monad in this case being IEnumerable/IQueryable.
There are other types, like Option<t>, Either<l,r>, Try<t> - see this library: [language-ext]
'let' is essentially the non-monadic assign, it's essentially exactly the same as declaring a local variable. It doesn't do the lifting, and therefore if you did 'let x = list', then it wouldn't extract the value from the list, it will just assign the list.
It's most useful in query expressions to pre-calculate a value that will be used many times in subsequent parts of the query; but it can very much allow full functional programming within LINQ expressions.
|
|
|
|
|
|
Quote: The agency has received 31 reports of people hospitalized due to the heart problems, including 10 deaths over the last 39 years.
But how many thousands are killed each year by Dupont, Monsanto...but that's OK because it's all in the name of profit and is acceptable collateral damage.
Sorry bout the rant in a really crappy mood this morning!
New version: WinHeist Version 2.2.2 Beta I told my psychiatrist that I was hearing voices in my head. He said you don't have a psychiatrist!
|
|
|
|
|
Mike Hankey wrote: collateral damage
"Colorectal" adjective could fit there, too.
You always obtain more by being rather polite and armed than polite only.
|
|
|
|
|
So - taking a lot of anti-diarrhea medication is suddenly news?
Damn it man - don't you know there's been a world-wide cult of such abusers for generations!
They're called "Politicians" and they're obviously full of sh . . .
Ravings en masse^ |
---|
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein | "If you are searching for perfection in others, then you seek disappointment. If you are seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010 |
|
|
|
|
|
Politicians can't be overdosing on anti-diarrhea medications. Have you heard what comes out of their mouths?
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
And that's why they're always contradicting themselves:
So full of it that it spews out of their mouth for lack of space.
(A circle of life thing, in some way)
Ravings en masse^ |
---|
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein | "If you are searching for perfection in others, then you seek disappointment. If you are seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010 |
|
|
|
|
|
Daniel Pfeffer wrote: Have you heard what comes out of their mouths?
The anti-diarrhoea medication only stops it coming out of the other end. Once it backs up far enough, there's only one exit it can use.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That would indicate that something's wrong with their plumbing.
|
|
|
|
|
why are there 3 pictures of the FDA headquarters on this article?
|
|
|
|
|
Why "only in America"?
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|