将字符串数组连接成 "string1, string2 或 string3"

11

考虑下面的代码:

string[] s = new[] { "Rob", "Jane", "Freddy" };

string joined = string.Join(", ", s);

// joined equals "Rob, Jane, Freddy"

出于界面设计的原因,我可能希望显示字符串"Rob, Jane or Freddy"

有什么建议可以最简明地实现这个目标吗?

编辑

我正在寻找一种打字简洁的方法。由于我只需要连接少量(小于10)的字符串,所以我不担心运行时性能。


字符串数组 s = new[] { "Rob", "Jane", "Freddy" }; Console.WriteLine(s.BetterJoin(", ", " 或者 ")); 这对我来说非常简洁,看看我的答案。Samuel 的答案也很棒 - Fabian Vilers
7个回答

9

您需要简单地输入文本,还是运行程序?如果要运行程序,使用 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();
}

通常情况下,在英语中,您会使用“或”将最后一项与其他项分开,除非只有两个项目。您的第一个解决方案(在我看来很不错)需要再添加一个情况来处理这种情况。 - Svante
@Svante:在英语中,两种方式都是可以接受的。是否在最后一个分隔符处包含逗号取决于个人喜好。 - Samuel
1
公司可能有首选风格,因此请与技术撰稿人确认。Svante,它被称为牛津逗号,还有其他名称,它是一个广受讨论的话题,但这些都不是我们在这里讨论的主题。 - Rob Kennedy
同意牛津逗号的讨论是离题的! :-) - Richard Ev

7

连接除最后一个外的所有内容。最后一个手动处理。


6
在 string[] 上创建一个扩展方法,实现与 string.Join 相同的逻辑,但最后一项将附加上 "or"。
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();
        }
    }
}

提供的代码并不是百分之百可靠的,它只是为了给你提供一个方向。 - Fabian Vilers

4

怎么样:

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] : "";
}

3

最节省内存和可扩展性的方法是使用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 ");

3

针对任何类型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"

0
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ı

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接