I've tried some answers from Stackoverflow but they don't count register of the symbols. For example
sTreSS => T (not 's'), stress => t
Here is what i tried
public static char FirstNonRepeatedCharacter(string s)
{
var output = s.GroupBy(item => item).First(x => x.Count() == 1).Key;
return output;
}
I need to edit the code with case-insensitive and return the correct register
sEVeraL -> s; - SomeBody - S
CodePudding user response:
This is exactly what you need, but not fully in LINQ. In my opinion, you don't have to strictly rely on LINQ...
Console.WriteLine(FirstNonRepeatedCharacter("sTreSS"));
Console.WriteLine(FirstNonRepeatedCharacter("stress"));
Console.WriteLine(FirstNonRepeatedCharacter("sEVeraL"));
Console.WriteLine(FirstNonRepeatedCharacter("SomeBody"));
Console.WriteLine(FirstNonRepeatedCharacter("AaBbCc"));
Console.ReadKey();
static char? FirstNonRepeatedCharacter(string s)
{
// Gather the count for each character (case insensitive, example: 's' and 'S' is in the same group).
var counts = new Dictionary<char, int>();
foreach (var ch in s.ToLower())
{
counts[ch] = counts.TryGetValue(ch, out var count)
? count 1
: 1;
}
// Return first character with count 1.
return s.FirstOrDefault(ch => counts[char.ToLower(ch)] == 1);
}
Output is:
T
t
s
S
nothing (null)
CodePudding user response:
You can group by characters as they are, but by processed character:
.GroupBy(c => char.ToLower(c), c => c)
Code:
// either first not repeating character or '\0'
private static char FirstNonRepeatedCharacter(string s) => s
?.GroupBy(c => char.ToLower(c), c => c)
?.FirstOrDefault(g => g.Count() == 1)
?.First()
?? '\0';
Edit: if you want to return string
- "...I need to return an empty string..." -, you can group by string
while providing required comparer:
private static string FirstNonRepeatedCharacter(string s) => s
?.GroupBy(c => c.ToString(), StringComparer.OrdinalIgnoreCase)
?.FirstOrDefault(g => g.Count() == 1)
?.Key
?? "";