Ответ 1
Как насчет:
if (s.Length > 1)
{
uiText = string.Format("{0} and {1}", string.Join(", ", s, 0, s.Length - 1), s[s.Length - 1]);
}
else
{
uiText = s.Length > 0 ? s[0] : "";
}
Рассмотрим следующий код:
string[] s = new[] { "Rob", "Jane", "Freddy" };
string joined = string.Join(", ", s);
// joined equals "Rob, Jane, Freddy"
Для причин пользовательского интерфейса я вполне мог бы отобразить строку "Rob, Jane or Freddy"
.
Любые предложения о наиболее кратком способе сделать это?
Я ищу что-то краткое типа. Поскольку я конкатенирую только небольшие числа (< 10) строк, я не беспокоюсь о производительности во время выполнения.
Как насчет:
if (s.Length > 1)
{
uiText = string.Format("{0} and {1}", string.Join(", ", s, 0, s.Length - 1), s[s.Length - 1]);
}
else
{
uiText = s.Length > 0 ? s[0] : "";
}
Краткий смысл набирать? или запустить? Самый быстрый запуск будет с ручным управлением с StringBuilder
. Но напечатать, возможно ( отредактировать дескриптор 0/1 и т.д.):
string joined;
switch (s.Length) {
case 0: joined = ""; break;
case 1: joined = s[0]; break;
default:
joined = string.Join(", ", s, 0, s.Length - 1)
+ " or " + s[s.Length - 1];
break;
}
Подход StringBuilder
может выглядеть примерно так:
static string JoinOr(string[] values) {
switch (values.Length) {
case 0: return "";
case 1: return values[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.Length - 2; i++) {
sb.Append(values[i]).Append(", ");
}
return sb.Append(values[values.Length-2]).Append(" or ")
.Append(values[values.Length-1]).ToString();
}
Объединить все, кроме последнего. Сделайте последнее вручную.
Создайте метод расширения в строке [], который реализует ту же логику, что и string.Join, но последний элемент будет добавлен с помощью "или".
string[] s = new[] { "Rob", "Jane", "Freddy" };
Console.WriteLine(s.BetterJoin(", ", " or "));
//--- 8 < ----
namespace ExtensionMethods
{
public static class MyExtensions
{
public static string BetterJoin(this string[] items, string separator, string lastSeparator)
{
StringBuilder sb = new StringBuilder();
int length = items.Length - 2;
int i = 0;
while (i < length)
{
sb.AppendFormat("{0}{1}", items[i++], separator);
}
sb.AppendFormat("{0}{1}", items[i++], lastSeparator);
sb.AppendFormat("{0}", items[i]);
return sb.ToString();
}
}
}
Наибольшая эффективность памяти и масштабируемость будут использовать StringBuilder
и предварительную вычисление длины конечной строки для перераспределения буферов. (Это похоже на то, как работает метод String.Concat
.)
public static string Join(string[] items, string separator, string lastSeparator) {
int len = separator.Length * (items.Length - 2) + lastSeparator.Length;
foreach (string s in items) len += s.Length;
StringBuilder builder = new StringBuilder(len);
for (int i = 0; i < items.Length; i++) {
builder.Append(items[i]);
switch (items.Length - i) {
case 1: break;
case 2: builder.Append(lastSeparator); break;
default: builder.Append(separator); break;
}
}
return builder.ToString();
}
Использование:
string joined = Join(s, ", ", " or ");
Взаимное решение будет использовать рекурсивный алгоритм. Он хорошо работает для достаточно небольшого количества строк, но не очень хорошо масштабируется.
public static string Join(string[] items, int index , string separator, string lastSeparator) {
return items[index++] + (index == items.Length-1 ? lastSeparator + items[index] : separator + Join(items, index, separator, lastSeparator));
}
Использование:
string joined = Join(s, 0, ", ", " or ");
Общее решение для любого типа T
.
static class IEnumerableExtensions
{
public static string Join<T>(this IEnumerable<T> items,
string seperator, string lastSeperator)
{
var sep = "";
return items.Aggregate("", (current, item) =>
{
var result = String.Concat(current,
// not first OR not last
current == "" || !items.Last().Equals(item) ? sep : lastSeperator,
item.ToString());
sep = seperator;
return result;
});
}
}
Использование:
var three = new string[] { "Rob", "Jane", "Freddy" };
var two = new string[] { "Rob", "Jane" };
var one = new string[] { "Rob" };
var threeResult = three.Join(", ", " or "); // = "Rob, Jane or Freddy"
var twoResult = two.Join(", ", " or "); // = "Rob or Jane"
var oneResult = one.Join(", ", " or "); // = "Rob"
string[] name_storage = new[] { "emre" , "balc" };
name_storage[name_storage.Count() - 1] += "ı";
string name = name_storage[0];
string sur_name = name_storage[1];
divElement.InnerHtml += name + " - " + sur_name;
//result = emre - balcı