简体   繁体   English

CodeGo.net>如何在正确的地方产生与“和”的字符串

[英]c# - How to produce string with 'and' in the correct place

Here is the loop I have so far 这是我到目前为止的循环

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

The checkboxes all have text values of the days of the week. 复选框均具有星期几的文本值。 Monday, Tuesday ect. 星期一,星期二等

I want the end result to be one string that looks like "Monday, Tuesday and Friday" depending on the whether the box is check. 我希望最终结果是一个看起来像“星期一,星期二和星期五”的字符串,具体取决于是否选中该框。

The loop will change a bool so a know whether at least one checkbox is checked. 该循环将更改布尔值,以便知道是否至少选中了一个复选框。 This will be used in a if statement after where the produced string will be displayed so if none are checked no string will be displayed. 这将在if语句中使用,该语句将在显示生成的字符串的位置之后显示,因此如果未选中任何内容,则不会显示任何字符串。 I think this means it doesn't matter what the string looks like to start off with if that helps. 我认为这意味着如果有帮助,从字符串开始看起来是什么都没关系。

I hope I've been clear. 我希望我已经清楚了。 If you need more detail please ask. 如果您需要更多详细信息,请询问。

Thank you in advance. 先感谢您。


Current code: 当前代码:

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("*, ", "");

Can anyone see anything wrong with this? 谁能看到这有什么问题吗?

The easiest way I can think of is to change your foreach to a for loop. 我能想到的最简单的方法是将foreach更改for循环。 I don't have my IDE open at the moment, so I can't double check grabbing the controls but once you have a List<CheckBox> you can use (not necessary, just a little more straight-forward to my mind) you can end up with something like: 我目前没有打开我的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 + ", ");
}

That's very, very rough, and needs a lot of cleaning before you use it, but it should put you on a path that works. 这非常非常粗糙,在使用前需要进行大量清洁,但这应该可以使您工作。

Try this out. 试试看

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

This gets you an array containing only checked days, which you can use to determine whether 'and' is necessary, and apply simple string methods against. 这使您得到一个仅包含检查日的数组,可用于确定是否需要“和”,并针对其应用简单的字符串方法。

From here, apply string.Join() as @Garo recommends. 从这里,按照@Garo的建议应用string.Join()

Make it so the loop will keep track of all the days that you need to show the user (into a List or whatever). 做到这一点,以便循环将跟踪您需要向用户显示的所有日期(进入列表或其他日期)。 Then, after the loop, use string.Join to combine the first N-1 items with ", " and then a second string.Join to add the last item with " and ". 然后,在循环之后,使用string.Join将前N-1个项目与“,”组合,然后使用第二个字符串。Join将最后一个项目与“和”添加。

The easiest way to do this is to have two loops. 最简单的方法是有两个循环。 The first builds a list of checked controls. 第一个构建已检查控件的列表。 Then loop over the list you just built and do the string builder commands. 然后循环遍历刚刚构建的列表,并执行字符串生成器命令。

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
    }
}

Something like this should work: 这样的事情应该起作用:

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

A bit of an ugly solution but should work. 有点丑陋的解决方案,但应该可以。

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;
}
    // 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());

Here is another solution. 这是另一种解决方案。 I put some Init code to test it. 我放入一些Init代码进行测试。

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);
    } 
}

I voted for AllenG but you could do it this way too: 我投票支持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);

Here's my take on it: 这是我的看法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM