Aryan Firouzian
Aryan Firouzian

Reputation: 2016

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

Suppose we have a list of strings like below:

List<string> myList = new List<string>(){"one", "two", "three", "four"};

There are some items with the length of more than 3.

By the help of Linq I want to divide them into new items in the list, so the new list will have these items:

{"one", "two", "thr", "ee", "fou", "r"};

Don't ask me why Linq. I am a Linq fan and don't like unLinq code :D

Upvotes: 7

Views: 1055

Answers (3)

Ivan Stoev
Ivan Stoev

Reputation: 205599

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

Upvotes: 4

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

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.

Upvotes: 9

Jared Price
Jared Price

Reputation: 5375

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...

Upvotes: 5

Related Questions