C
C#ā€¢3y ago
malkav

Help refactor please? I might have missed something big here [Answered]

is there maybe a better way of writing this?
foreach (Experience experience in User.Profile.Experiences)
{
foreach (string method in experience.Methods)
{
foreach (string tag in Assignment.Tags)
{
_matchingTags.Add( new()
{
Tag = method,
Matches = string.Equals(method, tag, StringComparison.CurrentCultureIgnoreCase)
|| tag.ToLower().Contains(method.ToLower())
|| method.ToLower().Contains(tag.ToLower())
});
}

}
}
foreach (Experience experience in User.Profile.Experiences)
{
foreach (string method in experience.Methods)
{
foreach (string tag in Assignment.Tags)
{
_matchingTags.Add( new()
{
Tag = method,
Matches = string.Equals(method, tag, StringComparison.CurrentCultureIgnoreCase)
|| tag.ToLower().Contains(method.ToLower())
|| method.ToLower().Contains(tag.ToLower())
});
}

}
}
The idea here is that I have a list of an object, of which one of its properties (or fields) is Methods and I've got a second list of strings, which are the Tags I got to find the matching strings between them (with fuzzy preferably) here's an example list of the two:
public class Experience
{
// Equals and GetHashCode methods
// Other props
public List<string> Methods {get;set;}
}

private List<Experience> _experiences = new()
{ Methods = new() { ".NET", ".NET6.0", "C#" } };
private List<string> _tags = new()
{ ".NET", "C#", "Blazor", "Other" };
public class Experience
{
// Equals and GetHashCode methods
// Other props
public List<string> Methods {get;set;}
}

private List<Experience> _experiences = new()
{ Methods = new() { ".NET", ".NET6.0", "C#" } };
private List<string> _tags = new()
{ ".NET", "C#", "Blazor", "Other" };
Basically I have to create a method that calculates the matching "tags" so to speak between the two lists. Oh, additional note: I made a class MatchingTags that looks like this (just because I need both properties in the rest of the program)
public class MatchingTags
{
public string Tag {get;set;}
public bool Matches {get;set;}
}
public class MatchingTags
{
public string Tag {get;set;}
public bool Matches {get;set;}
}
60 Replies
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
yea I'm thinking Linq too šŸ˜…
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
I'm thinking I still follow šŸ˜… but I have to make a conditional for the tags and methods too: string.Equals(tag, method, StringComparison.CurrentCultureIgnoreCase) || tag.ToLower().Contains(method.ToLower()) || method.ToLower().Contains(tag.ToLower()) for the Matching property, and I have to select the method that is actually in the Tags list šŸ˜… hence I get confused afterward I'm calculating a percentage based on this list too but that was easy
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
the contains is supposed to be my "fuzzy" comparison
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
dude šŸ˜… I think you lost me. I'm still trying to figure out how to get both tags and methods matching up with the linq you sent
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
whelp, hang on. Lemme try and figure out what you made there IndexOf returns an int... you know this right? also this part:
.SelectMany(method =>
{
Assignment.Tags.Select(tag => new MatchingTags()
{
Tag = method,
Matches = false
|| tag.IndexOf(method, StringComparison.CurrentCultureIgnoreCase)
|| method.IndexOf(tag, StringComparison.CurrentCultureIgnoreCase)
})
})
.SelectMany(method =>
{
Assignment.Tags.Select(tag => new MatchingTags()
{
Tag = method,
Matches = false
|| tag.IndexOf(method, StringComparison.CurrentCultureIgnoreCase)
|| method.IndexOf(tag, StringComparison.CurrentCultureIgnoreCase)
})
})
is not valid C# (according to Rider) it gives me this:
The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly. Candidates are: System.Collections.Generic.IEnumerable<TResult> SelectMany<string,TResult>(this System.Collections.Generic.IEnumerable<string>, System.Func<string,System.Collections.Generic.IEnumerable<TResult>>) (in class Enumerable)
The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly. Candidates are: System.Collections.Generic.IEnumerable<TResult> SelectMany<string,TResult>(this System.Collections.Generic.IEnumerable<string>, System.Func<string,System.Collections.Generic.IEnumerable<TResult>>) (in class Enumerable)
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
but if this IndexOf >= 0 doesnt' that pretty much always make it true? I guess I don't know how IndexOf works then šŸ˜… I'll read up on it lol
MODiX
MODiXā€¢3y ago
tebeco#0205
REPL Result: Success
"aaa".IndexOf("B", StringComparison.CurrentCultureIgnoreCase)
"aaa".IndexOf("B", StringComparison.CurrentCultureIgnoreCase)
Result: int
-1
-1
Compile: 452.686ms | Execution: 25.759ms | React with āŒ to remove this embed.
MODiX
MODiXā€¢3y ago
tebeco#0205
REPL Result: Success
"aaa".IndexOf("A", StringComparison.CurrentCultureIgnoreCase)
"aaa".IndexOf("A", StringComparison.CurrentCultureIgnoreCase)
Result: int
0
0
Compile: 536.815ms | Execution: 25.470ms | React with āŒ to remove this embed.
malkav
malkavOPā€¢3y ago
fair enough
MODiX
MODiXā€¢3y ago
tebeco#0205
REPL Result: Success
"Baaa".IndexOf("A", StringComparison.CurrentCultureIgnoreCase)
"Baaa".IndexOf("A", StringComparison.CurrentCultureIgnoreCase)
Result: int
1
1
Compile: 456.006ms | Execution: 19.065ms | React with āŒ to remove this embed.
MODiX
MODiXā€¢3y ago
tebeco#0205
REPL Result: Success
"A".IndexOf("Baaa", StringComparison.CurrentCultureIgnoreCase)
"A".IndexOf("Baaa", StringComparison.CurrentCultureIgnoreCase)
Result: int
-1
-1
Compile: 525.744ms | Execution: 38.151ms | React with āŒ to remove this embed.
malkav
malkavOPā€¢3y ago
wait, how is the last one no match? while it ignores case?
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
what if the tag says Function Azure and the method says Azure Function does that still make it true then?
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
Oh, in that case how did this command work?
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
So that would be a false, but I need that to be a true because it's basically the same, but written different.
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
Also, this is still not entirely valid because of the error I shown before (plus you forgot the Select( tag => new XXX() ... part (the tag)
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
no, the tag part
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
okay, hang on. Let me grab a working list of both
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
Assignment.Tags
List<string> Tags = new() {
"Azure",
"Data platform",
"T-SQL",
" Infrastructure as Code",
" Bicep",
" Azure Logic Apps",
" Powershell"
}
List<string> Tags = new() {
"Azure",
"Data platform",
"T-SQL",
" Infrastructure as Code",
" Bicep",
" Azure Logic Apps",
" Powershell"
}
(Don't know why it added the spaces in front, but this is from the Database, next up is my "Methods" list)
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
what I meant you forgot is this > Select( tag => new() .... you had this: Select(new() ... it could not resolve tag.IndexOf(...
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
ero
eroā€¢3y ago
What's with the false || lol
malkav
malkavOPā€¢3y ago
Experience.Methods (from multiple Experiences)
"Dart",
"Flutter",
"Firebase",
"JavaScript Firebase Functions",
"Github",
"Yaml Pipelines",
"Firebase Authenticate",
"Svelte",
"Blazor",
"JavaScript",
"Bootstrap",
"TypeScript",
"C#",
"Azure Functions",
"NET6.0",
".NET",
"Azure Functions",
"Azure DevOps",
"ASP.NET",
".NET core",
"Azure",
"Azure Static Web App",
"Azure Cosmos Db",
"NuGet",
"Dart",
"Flutter",
"Firebase",
"JavaScript Firebase Functions",
"Github",
"Yaml Pipelines",
"Firebase Authenticate",
"Svelte",
"Blazor",
"JavaScript",
"Bootstrap",
"TypeScript",
"C#",
"Azure Functions",
"NET6.0",
".NET",
"Azure Functions",
"Azure DevOps",
"ASP.NET",
".NET core",
"Azure",
"Azure Static Web App",
"Azure Cosmos Db",
"NuGet",
lol is okay
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
ero
eroā€¢3y ago
Eugh Wow i hate that
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
I'm still getting this error:
The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly. Candidates are: System.Collections.Generic.IEnumerable<TResult> SelectMany<string,TResult>(this System.Collections.Generic.IEnumerable<string>, System.Func<string,System.Collections.Generic.IEnumerable<TResult>>) (in class Enumerable)
The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly. Candidates are: System.Collections.Generic.IEnumerable<TResult> SelectMany<string,TResult>(this System.Collections.Generic.IEnumerable<string>, System.Func<string,System.Collections.Generic.IEnumerable<TResult>>) (in class Enumerable)
at the last SelectMany
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiXā€¢3y ago
If your code is too long, you can post to https://paste.mod.gg/ and copy the link into chat for others to see your shared code!
malkav
malkavOPā€¢3y ago
I'll try to, give me a minute šŸ˜…
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
ero
eroā€¢3y ago
paste.mod.gg doesn't need to be single file You can have up to 5 tabs
malkav
malkavOPā€¢3y ago
I'm getting you the paste.mod
MODiX
MODiXā€¢3y ago
tebeco#0205
REPL Result: Success
var methods = new string[] {
"Dart",
"Flutter",
"Firebase",
"JavaScript Firebase Functions",
"Github",
"Yaml Pipelines",
"Firebase Authenticate",
"Svelte",
"Blazor",
"JavaScript",
"Bootstrap",
"TypeScript",
"C#",
"Azure Functions",
"NET6.0",
".NET",
"Azure Functions",
"Azure DevOps",
"ASP.NET",
".NET core",
"Azure",
"Azure Static Web App",
"Azure Cosmos Db",
"NuGet",
};

var experiences = new[] {
new {
Methods = methods
}
};

var tags = new string[] {
"Azure",
"Data platform",
"T-SQL",
" Infrastructure as Code",
" Bicep",
" Azure Logic Apps",
" Powershell"
};

var results =
experiences
.SelectMany(experience => experience.Methods)
.SelectMany(method =>
tags.Select(tag => new
{
Tag = method,
Matches = false
|| tag.IndexOf(method, StringComparison.CurrentCultureIgnoreCase) >= 0
|| method.IndexOf(tag, StringComparison.CurrentCultureIgnoreCase) >= 0
})
);

foreach (var result in results)
{
Console.WriteLine(result);
}
var methods = new string[] {
"Dart",
"Flutter",
"Firebase",
"JavaScript Firebase Functions",
"Github",
"Yaml Pipelines",
"Firebase Authenticate",
"Svelte",
"Blazor",
"JavaScript",
"Bootstrap",
"TypeScript",
"C#",
"Azure Functions",
"NET6.0",
".NET",
"Azure Functions",
"Azure DevOps",
"ASP.NET",
".NET core",
"Azure",
"Azure Static Web App",
"Azure Cosmos Db",
"NuGet",
};

var experiences = new[] {
new {
Methods = methods
}
};

var tags = new string[] {
"Azure",
"Data platform",
"T-SQL",
" Infrastructure as Code",
" Bicep",
" Azure Logic Apps",
" Powershell"
};

var results =
experiences
.SelectMany(experience => experience.Methods)
.SelectMany(method =>
tags.Select(tag => new
{
Tag = method,
Matches = false
|| tag.IndexOf(method, StringComparison.CurrentCultureIgnoreCase) >= 0
|| method.IndexOf(tag, StringComparison.CurrentCultureIgnoreCase) >= 0
})
);

foreach (var result in results)
{
Console.WriteLine(result);
}
Console Output
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = Fa
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Dart, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Flutter, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = Firebase, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = False }
{ Tag = JavaScript Firebase Functions, Matches = Fa
Compile: 774.203ms | Execution: 138.220ms | React with āŒ to remove this embed.
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
what I'm getting now is a much too long list of items though šŸ˜… the list seems to keep on going, adding the same tags five or six times
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
Ooh, no, I figured it out šŸ˜… it lists every tag the user has in his Experiences items šŸ˜… I think it actually works now šŸ˜… your help with Linq was awesome, thanks for that it was this bit that messed up the rest afterward
<div id="mae-collapse-match-@(User.Profile?.Personalia.FullName?.Replace(" ", ""))" class="accordion-collapse collapse pt-1" aria-labelledby="mae-heading-match-@(User.Profile?.Personalia.FullName?.Replace(" ", ""))">
@{
foreach (MatchingTags item in _matchingTags.OrderBy(x => !x.Matches))
{
<div class="badge @(item.Matches ? "bg-success" : "bg-secondary") m-1">@(item.Tag)</div>
}
}
</div>
<div id="mae-collapse-match-@(User.Profile?.Personalia.FullName?.Replace(" ", ""))" class="accordion-collapse collapse pt-1" aria-labelledby="mae-heading-match-@(User.Profile?.Personalia.FullName?.Replace(" ", ""))">
@{
foreach (MatchingTags item in _matchingTags.OrderBy(x => !x.Matches))
{
<div class="badge @(item.Matches ? "bg-success" : "bg-secondary") m-1">@(item.Tag)</div>
}
}
</div>
but this is the fixed version, and it lists everything awesomely
malkav
malkavOPā€¢3y ago
Just the percentage bit needs to be fixed
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
Don't even get me started on why the LIst šŸ˜… my colleage has been messing things up, and I'm here now to fix it lol. So let's not go there in this topic shall we?
Unknown User
Unknown Userā€¢3y ago
Message Not Public
Sign In & Join Server To View
malkav
malkavOPā€¢3y ago
Thanks!
Accord
Accordā€¢3y ago
āœ… This post has been marked as answered!

Did you find this page helpful?