2013-01-02 4 views
14

カンマ区切りのリストをC#で最後の区切り文字として "and"を付けて作成します。コンマで区切られた最後のカンマの代わりに "and"を使用したリスト

string.Join(", ", someStringArray) 

この

Apple, Banana, Pear 

のような文字列になりますが、代わりに私はそれは次のようになりたい:

Apple, Banana and Pear 

は、LINQのとそれを達成するための簡単な方法があるとループを使用しないで?

+0

アイテムは、現在の順序と同じ順序で表示する必要がありますか、または並べ替えることはできますか? –

+0

これらは同じ順序でなければなりません。 – bytecode77

+4

'ループを使用せずに - 答えが証明されるので、これに明示的なループは必要ありません。しかし、ループはほとんど悪くなく、LINQは本当にあなたのためにループを生成しています。 –

答えて

22

あなたは最後のものを除くすべての項目に参加し、手動で最後の項目を追加できます:

using System; 
using System.Linq; 

namespace Stackoverflow 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DumpResult(new string[] { }); 
      DumpResult(new string[] { "Apple" }); 
      DumpResult(new string[] { "Apple", "Banana" }); 
      DumpResult(new string[] { "Apple", "Banana", "Pear" }); 
     } 

     private static void DumpResult(string[] someStringArray) 
     { 
      string result = string.Join(", ", someStringArray.Take(someStringArray.Length - 1)) + (someStringArray.Length <= 1 ? "" : " and ") + someStringArray.LastOrDefault(); 
      Console.WriteLine(result); 
     } 
    } 
} 

あなたが見ることができるように、そこの項目の金額のチェックであり、それは必要かどう決めます'と'の部分を追加します。

+1

いいですが、リストに2つ以下のアイテムが含まれているとどうなりますか? –

+1

次に、これを使用する必要があります:string days = string.Join( "、"、notSentDays.Count - 1)notSentDays.Count == 1 "": "and")+ notSentDays 。最終(); – bytecode77

+0

私は 'IEnumerable 'オーバーロードよりも 'string、string []、int、int'オーバーロードを使いたいでしょう。 – Rawling

11

一つの可能​​な解決策:それはICollection<string>(リストと配列は、それを実装して)実装していない場合、この文はsomeStringArrayを複数回繰り返すことができること

var items = someStringArray; // someStringArray.ToList() if not a ICollection<> 
var s = string.Join(", ", items.Take(items.Count() - 1)) + 
     (items.Count() > 1 ? " and " : "") + items.LastOrDefault(); 

注意。そうであれば、あなたのコレクションでリストを作成し、それに関するクエリを実行します。

+0

0,1および2+のエントリで完全に動作します。ニース! –

+1

@JonB:「0件のエントリで完璧に動作する」とはどういう意味ですか?何が起こるはずですか? –

+0

@MarkByers - 例外を引き起こすか、 "、"、 "と"のようなものを返すのではなく、 ""を返します。 –

2

Linqでループを使用しないで簡単に実現する方法はありますか?

ループなしでは不可能です。 Forループが最適に動作します。 LINQクエリは複数のループを使用します。

string Combine (IEnumerable<string> list) 
    { 
     bool start = true; 
     var last = string.Empty; 
     String str = string.Empty; 

     foreach(var item in list) 
     { 
      if (!start) 
      { 
       str = str + " , " + item; 
       last = item; 

      } 
      else 
      { 
       str = item; 
       start = false; 
      } 

     } 

     if (!string.IsNullOrWhiteSpace(last)) 
     { 
      str = str.Replace(" , " + last, " and " + last); 
     } 

     return str; 
    } 
+0

非常に読みやすく理解しています。 – SoftwareCarpenter

+0

リストが十分に長い場合は、複数のループでパフォーマンスの問題が発生する可能性があります。おおよそ5つのエントリーがあるので、パフォーマンスは重要ではありません。 Linqを使う理由は、スパゲッティコードを避けることです。このプロジェクトでは約10人が作業していますので、このような読みやすさのためにパフォーマンスを交換することはできません。しかし、あなたの答えに感謝します。 – bytecode77

+2

@Devils、複数のエントリがある場合 'String'の代わりに' StringBuilder'を使います。それ以外の場合は、他の 'LINQ'クエリよりも効率的です。私は常にLINQですべてのことをしようとしますが、パフォーマンス上の問題が発生した場合、LINQを使用して最悪のコードを書くのは簡単です> – Tilak

関連する問題