Пересечение списка в бритве и добавление разделителя между элементами
У меня есть список элементов, которые я хочу выводить в виде бритвы. Между каждым элементом я хочу добавить разделительную линию, например:
item1 | item2 | item3
Самый простой способ перебора элементов - с помощью foreach:
@foreach(var item in Model.items){
<span>@item.Name</span> |
}
К сожалению, это добавляет дополнительную строку разделителя в конце списка. Есть ли простой способ пропустить эту последнюю разделительную линию?
Ответы
Ответ 1
Вы можете использовать string.Join
:
@Html.Raw(string.Join("|", model.Items.Select(s => string.Format("<span>{0}</span>", s.Name))))
Использование string.Join
отменяет необходимость проверки последнего элемента.
Вы можете смешать это с помощью метода Razor @helper
для более сложной разметки:
@helper ComplexMarkup(ItemType item)
{
<span>@item.Name</span>
}
@Html.Raw(string.Join("|", model.Items.Select(s => ComplexMarkup(s))))
Вы даже можете создать вспомогательный метод для абстрактного вызова Html.Raw()
и string.Join()
:
public static HtmlString LoopWithSeparator
(this HtmlHelper helper, string separator, IEnumerable<object> items)
{
return new HtmlString
(helper.Raw(string.Join(separator, items)).ToHtmlString());
}
Использование:
@Html.LoopWithSeparator("|", model.Items.Select(s => ComplexMarkup(s)))
Ответ 2
Не уверен, что это самый простой способ, или если это более элегантный способ, но вы можете сделать что-то вроде:
@foreach ( var item in Model.items){
<span>@item.Name</span> @(Model.items[Model.items.Count - 1] != item ? "|" : "")
}
Итак, вы в основном проверяете, является ли item
последним элементом в списке.
Не пробовал этот образец кода, поэтому вам может потребоваться его подправить.
Ответ 3
Сохраните переменную счетчика и внутри цикла и проверьте, является ли это последним элементом или нет.
@{ int counter=0; }
@foreach(var item in Model.items){
counter++;
<span>@item.Name</span>
if(counter<Model.Items.Count)
{
@Html.Raw("|")
}
}
а короткая версия
@{ int counter=0; }
@foreach(var item in Model.items){
counter++;
<span>@item.Name</span> @(counter< Model.items.Count?"|":"")
}
Ответ 4
Объединив другие ответы здесь с этой статьей на встроенных шаблонах, я придумал этот вспомогательный метод, который можно поместить в класс расширения
public static HelperResult Join<T>(this IEnumerable<T> list, Func<T, HelperResult> template, Func<T, HelperResult> separator)
{
var first = true;
var result = new HelperResult(writer =>
{
foreach (var item in list)
{
if (first == false)
separator(item).WriteTo(writer);
first = false;
template(item).WriteTo(writer);
}
});
return result;
}
Тогда его можно было бы использовать
@Model.ListOfItems.Join(
@<a href="@item.Href">
@item.Name
</a>,
@<text> | </text>)
Это поддерживает html как в элементах, так и в разделителе.