0

I have the following foreach loop:

  var myString = "";
  foreach (var item in myList)
  {
      myString += GetItems(item.ID);
  }

Can this be converted to a List.ForEach. I was trying to do something like this:

myList.ForEach(s => GetItems(s.ID));

But I'm not sure how to return a string with concatenated ids this way.

Rich
  • 6,470
  • 15
  • 32
  • 53
  • 9
    It *can* - but why would you want to? I would personally change it to `var myString = string.Join(myList.Select(item => GetItems(item.ID)));` – Jon Skeet Apr 15 '22 at 14:38
  • 1
    Thanks a lot. I used this: var myString = string.Join("|", myList.Select(item => GetItems(item.ID))); I originally had the pipe in the GetItems function, but it would be better here. – Rich Apr 15 '22 at 15:13

3 Answers3

3
string.Join("", myList.Select(item => item.GetItems(item.Id));
Ian Newson
  • 7,679
  • 2
  • 47
  • 80
  • 2
    `string.Concat()` would be better – Matthew Watson Apr 15 '22 at 14:41
  • @MatthewWatson Possibly, but I have a suspicion their use case will end up needing some kind of separator in which they would need to use `Join`. – Ian Newson Apr 15 '22 at 14:44
  • I would use a StringBuilder because it is much faster for a large set of data: https://stackoverflow.com/questions/1612797/string-concatenation-vs-string-builder-performance – D A Apr 15 '22 at 14:45
  • 1
    @DA It would be faster but requires more code, and I think the questioner was favouring brevity, as otherwise there'd be no reason to change their code at all. – Ian Newson Apr 15 '22 at 14:47
  • 1
    `StringBuilder` is NOT faster than `string.Concat(IEnumerable)`, which is highly optimised (it uses [`ValueStringBuilder`](https://andrewlock.net/a-deep-dive-on-stringbuilder-part-6-vaulestringbuilder-a-stack-based-string-builder/)) – Matthew Watson Apr 15 '22 at 14:49
  • Similarly, `string.Join()` is also optimised to use `ValueStingBuilder` or (in the case that the `IEnumerable` is actually a `List` or `string[]`) it uses an ever better optimisation. – Matthew Watson Apr 15 '22 at 15:51
  • 2
    @MatthewWatson I just benchmarked it, `StringBuilder` is faster than `Concat` and `Join`: https://gist.github.com/IanPNewson/eef84733f9186bbca31e713fd9f306c9 – Ian Newson Apr 15 '22 at 19:31
  • 1
    @IanNewson I tried your benchmark, but changed the Random to `new Random(87234)` (to make the results reproducable, choosing an arbitrary fixed seed) and changed the target to `RuntimeMoniker.Net60` and got the following results: `Join 114.1us, Concat 144.2us, StringBuilder 139.5us`. The concat and StringBuilder times are pretty much the same and `Join` is slightly faster. In any case the salient point is that `StringBuilder` is not "much faster", which is the statement to which I objected. – Matthew Watson Apr 16 '22 at 09:26
  • 1
    I also tried the benchmark with `maxLength = 40` with the following results: `Join 254.6us, Concat 255.3us, StringBuilder 342.3us` so we can see that as the data size increases, `StrngBuilder` falls further behind. – Matthew Watson Apr 16 '22 at 09:37
  • @MatthewWatson Interesting, thanks! Tbh my takeaway from all this is that it's probably unnecessary to care about the performance difference of the three in most use cases :) – Ian Newson Apr 16 '22 at 10:28
1

What about aggregate?

var res= myList.Aggregate(
  new StringBuilder(),
 (b,s)=> b.Append(s)).ToString()
user2147873
  • 107
  • 5
-1

Use can use this also :

items.Select(i => i.Boo).Aggregate((i, j) => i + delimiter + j)

you can see this answer

mostafa kazemi
  • 514
  • 6
  • 7
  • Sorry but this isn't performant at all, it's roughly 10^3 times slower than `StringBuilder`, `Join` or `Concat`: https://gist.github.com/IanPNewson/c93d2e274ee538cbf6fd5b7a11477962 – Ian Newson Apr 16 '22 at 13:17