开发者

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

开发者 https://www.devze.com 2023-01-10 15:48 出处:网络
Here is the loop I have so far foreach (CheckBox chk in gpbSchedule.Controls.OfType<CheckBox>())

Here is the loop I have so far

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

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. 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. 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:

//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.


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 ".


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.

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:

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

精彩评论

暂无评论...
验证码 换一张
取 消