Modify list of strings to only have max n-length strings (use of Linq)

For real code basic for would likely be better (i.e. as shown in other answer.

If you really need LINQ split string into 3-letter chunks and than merge all with SelectMany:

var list = new[]{"", "a", "abc","dee","eff","aa","rewqs"};
var result = list
  .Select( 
    s => 
      Enumerable.Range(0, s.Length / 3 + 
             (s.Length == 0 || (s.Length % 3 > 0) ? 1 : 0))
      .Select(i => s.Substring(
         i * 3,
         Math.Min(s.Length - i * 3, 3))))
  .SelectMany(x=>x);

Range creates enumerable for all segments of the string (which is either length/3 if all pieces are exactly 3 characters, or one more if last one is shorter than 3 character).

.Select(i => s.Substring... splits string into chunks of 3 or less characters (need to carefully adjust length to avoid index out of range error)

.SelectMany combines list of list of 3 character segments into flat list of 3 character segments.


Note: This LINQ code should be used for entertainment/learning purposes. If you must use similar LINQ solution in production code at least convert splitting of string into more readable helper function.


I'm not sure you can do that with Linq. Here is a non-linq solution:

for (int x = 0; x < myList.Count; x++)
{
    if (myList[x].Length > 3)
    {
        var oldString = myList[x];
        myList[x] = oldString.Substring(0, 3);
        myList.Insert(x + 1, oldString.Substring(3));
    }
}

Edit: Apparently you can do that with Linq. Well, this is a non-linq solution anyways...


I see I'm late while was preparing my answer, which is basically the same as the accepted, but I'm posting it mainly to present the query syntax solution, which in this case IMO is more readable

var result =
    (from s in myList
     from i in Enumerable.Range(0, 1 + (s.Length - 1) / 3)
     let start = i * 3
     let length = Math.Min(3, s.Length - start)
     select s.Substring(start, length))
     .ToList();

Tags:

C#

Linq

String

List