using substring and foreach in a lambda expression - c#

Dictionary<int, string> names= GetNames().Where(x =>
x.Value.StartsWith("test") | x.Value.StartsWith(" " + "test")).ToDictionary(x => x.Key, y => y.Value);
The values from the getNames() method are something like this:
John Testing
Test Travis
Test Metsaoy
Using the above line of code I'm getting only the two last entries, but I want also the 1st one because the 2nd string starts with "test".
So, I need to modify the above where statement. I tried something like this:
.Where(x =>
foreach ( xx in x.Value.Split(' ') ) { if ( xx.StartsWith("text") ) true; })
How can I achieve this?

var res = GetNames().Where(kvp => kvp.Value.Split()
.Any(s => s.StartsWith("Test") || s.StartsWith("test")));
Optionally instead of StartsWith you can use String.Contains in the Any lambda.

Try:
var parser = new Regex(#"\bTest", RegexOptions.Compiled);
GetNames().Where(x => parser.IsMatch(x.Value)).ToDictionary(x => x.Key, y => y.Value)

Have you tried this?
x.Value.StartsWith("test") || x.Value.Contains(" test")
You'll have to use it in your query like this:
var names= GetNames()
.Where(x => x.Value.StartsWith("test") || x.Value.Contains(" test"))
.ToDictionary(x => x.Key, y => y.Value);
Hope it helps

Related

No overload for method 'Join' takes 1 arguments

What he wants me to do here for Join can you help me solve the problem?
this.Parts
.Join(this.PartInformation, p => p.PartId, pi => pi.PartId, (p, pi) => new
{
p.ListId,
p.PartId,
pi.PartDescription
});
I think you want the static string.Join method instead:
.ToDictionary(x => x.Key, x => string.Join(";", x.Select(a => a.UrlPrefix)))
Your method signature suggests you need to use string.Join:
var result = data
.GroupBy(x => x.DomainId)
.ToDictionary(x => x.Key, x => string.Join(";", x.Select(a => a.UrlPrefix)));

How to use lambda expression for below code block?

I am writing a piece of code in order to get values from the server. There are multiple code lines and need to do the same thing using lambda expressions. This is the code I have tried and please help to rewrite this code using lambda expressions.
var newDocuments = result?.DocumentQueryResults.OrderBy(d => context.GetParams().GetAllDocumentIds().ToList().IndexOf(d.Document.Id)).ToList();
var test = new List<HealthRecord>();
foreach (DocumentQueryResult item in newDocuments)
{
test.Add(item.Document);
}
I believe you're looking for something like this:
// Cache the sort parameters, as suggested by Caius Jard:
var sortParams = context.GetParams()
.GetAllDocumentIds()
.AsEnumerable()
.Select((id, index) => new { id, index })
.ToDictionary(x => x.id, x => x.index);
var test = result?.DocumentQueryResults
.OrderBy(d => sortParams[d.Document.Id])
.Select(d => d.Document)
.ToList();

Multiple GroupBy in 1 linq expression

I cannot seem to combine 2 GroupBy statements in 1 linq expression..
For now i'm doing something like this:
double maxInvestment = 0;
foreach (var playerAction in TotalUserActions.GroupBy(p => p.Player))
{
var MaxInvestmentPerPlayer = playerAction.GroupBy(p => p.RoundId)
.Select(p => p.LastOrDefault())
.Sum(p=> p.BetSize);
if(MaxInvestmentPerPlayer > maxInvestment)
maxInvestment = MaxInvestmentPerPlayer;
}
What I would like to do is something like this...
double maxInvestment = TotalUserActions.GroupBy(p => p.Player)
.GroupBy(p => p.RoundId)
.Select(p => p.LastOrDefault())
.Sum(p=> p.BetSize);
But that wont work.. Can someone help me on this?
Thanks!
Looks like this is what you want, the key takeaway being the inner query is wrapped in an outer call to Select():
var maxInvestment = TotalUserActions.GroupBy(p => p.Player)
.Select(g => g.GroupBy(x => x.RoundId)
.Select(x => x.LastOrDefault())
.Sum(x => x.BetSize))
.Max();
I do question your use of LastOrDefault() though as, since you have not specified any ordering, you may as well use FirstOrDefault() and save the hassle of skipping to the last element.

Entity Framework incremented index property for groups

I'd like to have an int property that is incremented for each item in group independently (as described here, because quotes need to be accessible like /person/quote/1..2..3 not /person/quote/1..5..10:
Quote Person Index
Lorem Smith 1
Ipsum Smith 2
Loremi Lewis 1
Ipsumi Lewis 2
Using code in that question with EF:
var query = _data.Quotes
.GroupBy(x => x.Person.Name)
.Select
(
x => x.Select((y, i) => new { y.Text, y.Person.Name, Index = i + 1 })
)
.SelectMany(x => x);
But EF cannot parse it and returns NotSupportedException exception:
LINQ to Entities does not recognize the method
System.Collections.Generic.IEnumerable`1[<>f__AnonymousType9`2[System.String,System.Int32]] Select[Quote,<>f__AnonymousType9`2](System.Collections.Generic.IEnumerable`1[App.Models.Quote], System.Func`3[App.Models.Quote,System.Int32,<>f__AnonymousType9`2[System.String,System.Int32]]) and this method cannot be translated into a store expression
Thanks to Dabblernl's comment this code is working:
var query = _data.Quotes
.GroupBy(x => x.Person.Name)
.ToList()
.Select
(
x => x.Select((y, i) => new { y.Person.Name, y.Text, Index = i + 1 })
)
.SelectMany(x => x);
Query:
var query = _data.Quotes
.GroupBy(x => x.Person.Name.ToLower())
.Select
(
x => x.Select((y, i) => new { y.Text.ToLower(), y.Person.Name.ToLower(), Index = i + 1 })
)
.SelectMany(x => x);

C# ToDictionary lambda select index and element?

I have a string like string strn = "abcdefghjiklmnopqrstuvwxyz" and want a dictionary like:
Dictionary<char,int>(){
{'a',0},
{'b',1},
{'c',2},
...
}
I've been trying things like
strn.ToDictionary((x,i) => x,(x,i)=>i);
...but I've been getting all sorts of errors about the delegate not taking two arguments, and unspecified arguments, and the like.
What am I doing wrong?
I would prefer hints over the answer so I have a mental trace of what I need to do for next time, but as per the nature of Stackoverflow, an answer is fine as well.
Use the .Select operator first:
strn
.Select((x, i) => new { Item = x, Index = i })
.ToDictionary(x => x.Item, x => x.Index);
What am I doing wrong?
You're assuming there is such an overload. Look at Enumerable.ToDictionary - there's no overload which provides the index. You can fake it though via a call to Select:
var dictionary = text.Select((value, index) => new { value, index })
.ToDictionary(pair => pair.value,
pair => pair.index);
You could try something like this:
string strn = "abcdefghjiklmnopqrstuvwxyz";
Dictionary<char,int> lookup = strn.ToCharArray()
.Select( ( c, i ) => new KeyValuePair<char,int>( c, i ) )
.ToDictionary( e => e.Key, e => e.Value );

Categories