Reputation: 1
I want a single line of code which converts a string array to char array(preferably using C# LINQ). It would be better if char array is distinct.
Upvotes: 0
Views: 624
Reputation: 30454
The .net class string implements IEnumerable<char>
.
This means, that whenever you see a string, you can regard it as if it is a sequence of characters.
Furthermore, if you have several sequences of similar types, and you want to regard it as one sequence consider to use Enumerable.Concat
Alas, Concat only works if you know at compile time how many sequences you have: it is easy to Concat two or three sequences. But if you don't know how many sequences you have, or if there are many sequences, you can't use Concat. It would be a nuisance to Concat 100 strings.
Enumerable.SelectMany to the rescue!
(by the way, I use sequence to prevent saying: list or array or collection or ...)
Whenever you have a sequence, where every element has zero or more sub-sequences, and you want to regard it as one big sequence, consider to use SelectMany.
So if you have a list of Schools, and every School has a list of Students, then if you want one big list of all Students on all Schools, use SelectMany.
In your case: you have a List of strings, and every string is a sequence of chars, and you want one big sequence of all chars in all strings: use SelectMany.
SelectMany has several overloads. The one that I use most often is the overload with a parameter resultSelector.
In my example of Schools and Students, I tell the Linq which sub-sequence you want to use, and in parameter resultSelector, you take one School, and one Student on this School to make one new object. Do this for all Schools and all Students.
IEnumerable<School> schools = ...
IEnumerable<Student> allStudentsOnAllSchools = schools.SelectMany(school => school.Students,
// parameter resultSelector: take a school and a student to make one new:
(school, student) => new
{
// select the properties that you want to use:
SchoolId = school.Id,
StudentId = student.Id,
Description = String.Format("Student {0} studies at school {1},
student.Name,
school.Name,
});
In words: from every School, take their students, and from every combination of [School, Student] make one new object containing the Ids of the School and the Student and a Description with the names of the School and the Student
Your case is similar, except that your string does not have a sequence of characters, it is a sequence of character. So your sub-sequence, is one element of your input sequence.
IEnumerable<string> lines = ...
IEnumerable<char> allUsedCharacters = lines.SelectMany(line => line,
(line, charInThisLine) => charInThisLine);
In words: from every line in the sequence of Lines, take all characters in this line. From the combination of [line, characterInThisLine], keep only the character in this line. You don't need the line anymore.
To remove duplicate characters, add:
.Distinct();
Upvotes: 0
Reputation: 460078
char[] distinctChars = stringArray.SelectMany(s => s).Distinct().ToArray();
This works because String
implements IEnumerable<char>
.
Upvotes: 3