Mohammed Shafique
Mohammed Shafique

Reputation: 1

Is there a way to convert a string array into char array using LINQ?

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

Answers (2)

Harald Coppoolse
Harald Coppoolse

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

Tim Schmelter
Tim Schmelter

Reputation: 460078

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

This works because String implements IEnumerable<char>.

Upvotes: 3

Related Questions