Как создать строку с 'и' в правильном месте - PullRequest
2 голосов
/ 09 августа 2010

Вот цикл, который у меня пока есть

foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())
                {
                    if (chk.Checked)
                    {
                        //Code goes here
                    }
                }

Все флажки имеют текстовые значения дней недели. Понедельник, вторник и т. Д.

Я хочу, чтобы конечный результат представлял собой одну строку, которая выглядит как «Понедельник, Вторник и Пятница» в зависимости от того, установлен ли флажок.

Цикл изменит бул, чтобы знать, установлен ли хотя бы один флажок. Это будет использоваться в операторе if после того, где будет отображаться произведенная строка, поэтому, если ни одна из них не отмечена, строка не будет отображаться. Я думаю, это означает, что не имеет значения, как выглядит строка, если это поможет.

Надеюсь, мне все ясно. Если вам нужно больше деталей, пожалуйста, спросите.

Заранее спасибо.


Текущий код:

string days = "*";
        foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())
        {
            if (chk.Checked)
            {
                days += "#" + chk.Text;
            }
        }

        days = days.Insert(days.LastIndexOf('#'), " and ");
        days = days.Remove(days.LastIndexOf('#'), 1);
        days = days.Replace("#", ", ");
        days = days.Replace("* and ", "");
        days = days.Replace("*, ", "");

Может кто-нибудь увидеть что-то не так с этим?

Ответы [ 10 ]

3 голосов
/ 09 августа 2010

Самый простой способ, который я могу придумать, - это поменять foreach на for цикл. В данный момент у меня нет открытой IDE, поэтому я не могу дважды проверить захват элементов управления, но когда у вас есть List<CheckBox>, вы можете использовать (не обязательно, просто немного более прямо на мой взгляд), вы можете в конечном итоге что-то вроде:

//ckBoxes is our List<CheckBox>
for(int i = 0; i < ckBoxes.Count; i++)
{
  StringBuilder listBuilder = new StringBuilder;
  if(i == ckBoxes.Count -1)
  {
    listBuilder.Append("and " + dayOfWeek)
  }
  else listBuilder.Append(dayOfWeek + ", ");
}

Это очень, очень грубо и требует большой очистки, прежде чем использовать его, но это должно поставить вас на путь, который работает.

1 голос
/ 09 августа 2010

Попробуйте это.

var days = gpbSchecule.Controls.OfType<CheckBox>()
                               .Where(x => x.Checked)
                               .Select(x => x.Text)
                               .ToArray();

Это дает вам массив, содержащий только проверенные дни, которые вы можете использовать для определения необходимости 'и' и применения простых строковых методов против.

Отсюда примените string.Join(), как рекомендует @Garo.

0 голосов
/ 09 августа 2010

Вот мое мнение:

var darr = (from checkbox in gpbSchecule.Controls.OfType<CheckBox>()
            where checkbox.Checked
            select checkbox.Text)
           .ToArray();

string days = "";
if (darr.Length > 0)
{
    days = string.Join(", ", darr.Take(darr.Length - 1));
    if (darr.Length > 1)
        days += " and ";
    days += darr[darr.Length - 1];
}
0 голосов
/ 09 августа 2010

Я голосовал за AllenG, но вы могли бы сделать это и так:

// First build a string of days separated by a coma
string days = String.Empty;
foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())
{
    if (chk.Checked)
    {
        if (!String.IsNullOrEmpty(days))
            days += ", ";
        days += chk.Text;            
    }
}

// Then replace the last coma with "and"            
int lastComaIndex = days.LastIndexOf(',');
if (lastComaIndex >= 0)
    days = days.Substring(0, lastComaIndex) + " and " + days.Substring(lastComaIndex + 2);
0 голосов
/ 09 августа 2010

Вот еще одно решение.Я положил код инициализации, чтобы проверить его.

private List<CheckBox> _checkBoxes;

private void Test()
{
    Init();

    List<CheckBox> checkedCheckBoxes = _checkBoxes.Where(cb => cb.Checked == true).ToList();
    StringBuilder str = new StringBuilder();
    string delimiter = String.Empty;

    for (int i = 0; i < checkedCheckBoxes.Count; i++)
    {
        str.Append(delimiter);
        str.Append(checkedCheckBoxes[i].Name);

        if (i != checkedCheckBoxes.Count)
        {
            if (i == checkedCheckBoxes.Count - 2)
                delimiter = " and ";
            else
                delimiter = ", ";
        }
    }

    Console.WriteLine(str.ToString());
    Console.ReadLine();
}

private void Init()
{
    _checkBoxes = new List<CheckBox>();

    string[] days = new string[7] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
    Random r = new Random();

    foreach (string day in days)
    {
        CheckBox cb = new CheckBox();
        cb.Name = day;
        cb.Checked = Convert.ToBoolean(r.Next(0, 2));
        _checkBoxes.Add(cb);
    } 
}
0 голосов
/ 09 августа 2010
    // change this into a collection of your checked group boxes
    string[] threeStrings = new string[] { "Joe", "Jim", "Robert" };
    StringBuilder newString = new StringBuilder();

    // iterate over your array here - strings used to simplify example
    for (int i = 0; i < threeStrings.Length; i++)
    {
        if (i < threeStrings.Length - 1)
        {
            newString.Append(threeStrings[i]);
            newString.Append(", ");
        }
        else
        {
            newString.Append(" and ");
            newString.Append(threeStrings[i]);
        }
    }
    Console.WriteLine(newString.ToString());
0 голосов
/ 09 августа 2010

Немного уродливое решение, но оно должно работать.

string result = "";
string nextDay = null;
foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())
{
    if (nextDay != null) {
      if (result.length() > 0) {
        result += ", " + nextDay;
      } else {
        result = nextDay;
      }
      nextDay = null;
    }
    if (chk.Checked)
    {
        //Code goes here
        nextDay = chk.text; // Your text here Monday, Tuesday, ...
    }
}

if (nextDay != null) {
  if (result.length() > 0) {
    result += " and " + nextDay;
  } else {
    result = nextDay;
  }
  nextDay = null;
}
0 голосов
/ 09 августа 2010

Примерно так должно работать:

var days = new List<string>();
foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())
{
    if (chk.Checked)
    {
        days.Add(chk.Text);
    }
}
string daysString = "";
if (days.Count == 1)
{
    daysString = days[0];
}
else if (days.Count > 1)
{
    daysString =
        string.Join(", ", days.Take(days.Count - 1)) +
        " and " +
        days[days.Count - 1];
}
0 голосов
/ 09 августа 2010

Самый простой способ сделать это - создать две петли. Первый строит список проверенных элементов управления. Затем переберите список, который вы только что создали, и выполните команды строителя строк.

List<CheckBox> checked = new List<CheckBox>();
foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())
{
    if (chk.Checked)
    {
        checked.Add(chk);
    }
}
for(int i = 0; i < checked.Count; i++)
{
    if (i == checked.Count-1))
    {
        //write for last element
    }
    else
    {
        //write for all other elements
    }
}
0 голосов
/ 09 августа 2010

Сделайте так, чтобы цикл отслеживал все дни, которые вам нужно показать пользователю (в Список или как угодно). Затем, после цикла, используйте string.Join, чтобы объединить первые N-1 элементы с «,», а затем вторую строку. Присоединитесь, чтобы добавить последний элемент с «и».

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