Как создать строку из коллекции имен - PullRequest
6 голосов
/ 23 июня 2011

У меня есть коллекция имен, которые нужно объединить в строку, разделенную запятыми.

Сгенерированная строка должна соответствовать правильной грамматике.

Если коллекция содержит одно имятогда на выходе должно быть только это имя:

John

Если коллекция содержит два имени, то выходные данные должны быть разделены словом "и":

John and Mary

Если коллекциясодержит три или более имен, тогда выходные данные должны быть разделены запятыми, а перед именем должно стоять слово «и»:

John, Mary, and Jane

Вот код, который я придумал.Это не очень элегантно, и я хотел бы знать, есть ли лучший способ сделать это в C # (4.0 в порядке).

List<string> firstNames = new List<string>();
firstNames.Add("John");
firstNames.Add("Mary");
firstNames.Add("Jane");

string names = string.Empty;
for (int i = 0; i < firstNames.Count; i++)
{
    if (i == 1 && firstNames.Count == 2)
    {
        names += " and ";
    }
    else if (firstNames.Count > 2 && i > 0 && i != firstNames.Count - 1)
    {
        names += ", ";
    }
    else if (i != 0 && i == firstNames.Count - 1)
    {
        names += ", and ";
    }

    names += firstNames[i];
}

Ответы [ 11 ]

6 голосов
/ 23 июня 2011

Я не думаю, что это станет более элегантным, чем:

 if (names.Count == 0)
     return "";

 if (names.Count == 1)
     return names[0];

 if (names.Count == 2)
     return names[0] + " and " + names[1];

 return String.Join(", ", names.Take(names.Count - 1)) +
     ", and "  + names[names.Count - 1];

Я не скомпилировал это, но я думаю, вы поняли идею.

РЕДАКТИРОВАТЬ: короче, но менее читабельным:

 if (names.Count <= 2)
     return String.Join(" and ", names);

 return String.Join(", ", names.Take(names.Count - 1)) + 
     ", and "  + names[names.Count - 1];
3 голосов
/ 23 июня 2011

Я бы сделал что-то вроде этого:

using System;
using System.Collections.Generic;

class Program {

    static void Main(string[] args) {
        List<string> firstNames = new List<string>();
        firstNames.Add("John");
        firstNames.Add("Mary");
        firstNames.Add("Jane");
        Console.WriteLine(NamesString(firstNames));
    }

    static string NamesString(List<string> firstNames) {
        switch (firstNames.Count) {
        case 0:
            return string.Empty;
        case 1:
            return firstNames[0];
        case 2:
            return string.Join(" and ", firstNames.ToArray());
        default:
            return string.Format("{0} and {1}",
                string.Join(", ", firstNames.ToArray(), 0, firstNames.Count - 1),
                firstNames[firstNames.Count - 1]);
        }
    }
}

РЕДАКТИРОВАТЬ : фактически должно быть

        default:
            return string.Format("{0}, and {1}",

, если вы хотите запятую перед последним "и".

2 голосов
/ 23 июня 2011
        string a=string.Join(",", FirstNames.ToArray());
        if (FirstNames.Count == 1)
            a.Replace(",", "");
        else if (FirstNames.Count == 2)
            a.Replace(",", " and ");
        else
        {
            int i = a.LastIndexOf(",");
            a = a.Substring(1, i) + a.Substring(i).Replace(",", " and ");
        }
1 голос
/ 23 июня 2011
    static string JoinNames(List<string> firstNames)
    {
        int count = firstNames.Count;
        if(count == 1)
        {
            return firstNames[0];
        }

        if(count > 1)
        {
            return string.Join(", ", firstNames.Take(count - 1).ToArray()) + " and " + firstNames[count - 1];
        }
        return string.Empty;
    }
0 голосов
/ 23 июня 2011
public string Combine(List<string> names)
{
    if (names == null || names.Count == 0)
    {
        return string.Empty;
    }

    var sb = new StringBuilder();
    sb.Append(names[0]);

    //Handle Special Case of 2 names
    if (names.Count == 2)
    {
        sb.Append(" and " + names[1])
        return sb.ToString();
    }

    for (int i = 1; i < names.Count; i++)          
    {
        if (i == (names.Count -1))
        { 
            sb.Append(", and " + names[i]);
        }
        else
        {
            sb.Append(", " + names[i]);
        }
    }

    return sb.ToString(); 
}
0 голосов
/ 23 июня 2011

Я предпочитаю код, который является наиболее читабельным. У вас есть 4 случая пунктуации, которые необходимо учитывать при добавлении имени в список, поэтому просто изложите их.

static string Combine(List<string> names)
{
    var sb = new StringBuilder();
    for (int i = 0; i < names.Count; i++)
    {
        if (i == 0) //at start of a list
            {}

        else if (i < names.Count - 1) //in middle of list
            sb.Append(", ");

        else if( names.Count == 2 ) //at end of a list with 2 elements
            sb.Append(" and ");

        else //at end of a list with 3 or more elements
            sb.Append(", and ");

        sb.Append(names[i]);
    }
    return sb.ToString();
}
0 голосов
/ 23 июня 2011
var a = String.Join(", ", firstNames.Skip(1).ToArray()) + (firstNames.Count < 2 ? "" : ", and ") + firstNames.Take(1).FirstOrDefault();
0 голосов
/ 23 июня 2011

Примерьте размер:

            List<string> firstNames = new List<string>();
            firstNames.Add("John");
            firstNames.Add("Mary");
            firstNames.Add("Jane");

            // Only do this if there is more than one name
            if (firstNames.Count > 1)
            {
                string separator = ", ";

                // Join the names, using ", " as a separator
                string names = String.Join(seperator, firstNames.ToArray());

                // Insert "and" before the last comma
                names = names.Insert(names.LastIndexOf(separator), ", and ");

                // Remove the last comma
                names = names.Remove(names.LastIndexOf(separator), separator.Length);
            }
0 голосов
/ 23 июня 2011

Вот интересное решение:

        //code
        List<string> firstNames = new List<string>();
        firstNames.Add("John");
        firstNames.Add("Mary");
        firstNames.Add("Jane");

        StringBuilder sb = new StringBuilder();
        firstNames.Take(firstNames.Count - 1).ToList().ForEach(fn => AddString(fn, sb));
        sb.Append(", and " + firstNames.Last());

    //Helper Function
    public void AddString (string fn, StringBuilder sb)
    {
        if (sb.Length != 0)
        {
            sb.Append(", ");
        }
        sb.Append(fn);
    }
0 голосов
/ 23 июня 2011
List<string> firstNames = new List<string>();
firstNames.Add("John");
firstNames.Add("Mary");
firstNames.Add("Jane");
int cnt = 0;
string names = string.Empty;
while (cnt<=firstName.Count)
{
    string separator = "";

    if (firstName.Count - cnt > 1) separator = ", ";

    else if (firstName.Count - cnt = 1) separator = ", and ";

    else separator = "";

    names += firstName[cnt] + separator;

    cnt += 1;


}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...