I have a List(Of String)
that stores validation errors. Should that list contain any items, I'd like to concatenate them into an HTML list to show each error. Currently this is easily done like so:
Dim l As List(Of String) = GetErrors()
If l.Count > 0 Then
Dim sb As New StringBuilder
sb.Append("<div><ul>")
For Each s As String In l
sb.Append(String.Format("<li>{0}</li>", s))
Next
sb.Append("</ul></div>")
ltl_status.Text = sb.ToString()
End If
However, because this is quite lengthy, I wondered whether Linq could provide a shortcut. I tried this (line breaks added for clarity):
If l.Count > 0 Then
ltl_status.Text = String.Format("<div class=""failure""><ul>{0}</ul></div>",
(
From s As String In l Select
String.Format("<li>{0}</li>", s)
)
)
End If
However, given that IEnumerable is a collection, the end result is just this output in the Literal:
System.Linq.Enumerable+WhereSelectListIterator`2[System.String,System.String]
The aim here is to build the list using the least possible lines of code. I see that String.Join
accepts an IEnumerable parameter, but that simply joins the items together, whereas here I need to add additional strings to the beginning and end of each item. Is it possible?
Based on Jon Skeet's excellent suggestions, the extension method has saved me a ton of time and effort:
Public Module CollectionSignatureMethods
''' <summary>
''' Takes each String value in a String collection, reformats using a format, and then returns all as a single String.
''' </summary>
''' <param name="ie">An IEnumerable(Of String) collection of string values</param>
''' <param name="formatString">The string format (as per String.Format)</param>
''' <returns>All of the Strings from the collection, reformatted and combined to a single String</returns>
''' <remarks>Jon Skeet is the daddy(!)</remarks>
<Extension()> _
Public Function JoinFormat(ie As IEnumerable(Of String), formatString As String) As String
Return String.Join(String.Empty, ie.Select(Function(s As String) String.Format(formatString, s)))
End Function
End Module
It sounds like you need a combination of Join
and Select
:
String.Join("", _
l.Select(Function(s as String) String.Format("<li>{0}</li>", s))
Of course, you could always write your own JoinFormat
extension method - that wouldn't be hard to do, and would be potentially useful all over the place. For example, you might then have:
ltl_status.Text = String.Format("<div class=""failure""><ul>{0}</ul></div>",
l.JoinFormat("<li>{0}</li>"));
See more on this question at Stackoverflow