0

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.

0

2 Answers 2

3
char[] distinctChars = stringArray.SelectMany(s => s).Distinct().ToArray();

This works because String implements IEnumerable<char>.

Sign up to request clarification or add additional context in comments.

6 Comments

You could actually make this slightly shorter (and much less efficient) using char[] distinctChars = string.Concat(stringArray).Distinct().ToArray(); ;)
It would be interesting to benchmark that: while on the face of it it's much less efficient, it involves the same number of allocations and significantly fewer method and delegate calls.
I wonder whether @MatthewWatson's string.Concat approach might be more efficient in practice
It doesn't: it allocates an empty string of the right length, and then copies the various concatted strings into it. It's in the realms of insignifiance either way, so it doesn't matter, it's just that @MatthewWatson caveated their suggestion with "and must less efficient", and that got me wondering as to whether it was less efficient. That's all.
Well I'm not sure about that @canton7 - string.Concat(string[]) appears to make a copy of the string array before concatenating it.
|
0

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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.