Lasse Edsvik
Lasse Edsvik

Reputation: 9298

Getting index + value for current in IEnumerable loop

I have a loop, where I need to use the values from 2 IEnumerable's, and I need to get the current index and value for "labels", so I can print out labelname for each one.

public static string CheckBoxList(this HtmlHelper htmlhelper, IEnumerable<string> values, IEnumerable<string> labels, string name, IDictionary<string, object> HtmlAttributes)
    {
        if (labels == null)
            return "";

        StringBuilder sb = new StringBuilder();


        string[] modelValues = new string[] {};

        ModelState modelState;

        if(htmlhelper.ViewData.ModelState.TryGetValue(name, out modelState)) {
            modelValues = ((string[])modelState.Value.RawValue);
        }


        foreach(string s in values)
        {
            bool isChecked = modelValues.Contains(s);

            sb.Append(CreateCheckBox(name, s, isChecked, HtmlAttributes));

            sb.Append(" <label for=\"" + name + "\"> " + labels + "</label><br />");
        }


        return sb.ToString();
    }

How can I print out current value for "labels" in that loop? Also I need the "index", need to build a unique ID for checkbox so label will work.

Thanks in advance. /M

Upvotes: 0

Views: 6518

Answers (2)

RaYell
RaYell

Reputation: 70444

If you want to use foreach loop then you need something like that:

int i = 0;
foreach (string s in values) {
    bool isChecked = modelValues.Contains(s);
    sb.Append(CreateCheckBox(name, s, isChecked, HtmlAttributes));
    sb.Append(" <label for=\"" + name + "\"> " + labels.ElementAt(i) + "</label><br />");
    i++;
}

However for loop may be better in this case

// IEnumerable doesn't have Count property so you need to use Count() 
// extension method from System.Linq namespace.
int length = values.Count();
for (int i = 0; i < length; i++) {
    bool isChecked = modelValues.Contains(values.ElementAt(i));
    sb.Append(CreateCheckBox(name, values.ElementAt(i), isChecked, HtmlAttributes));
    sb.Append(" <label for=\"" + name + "\"> " + labels.ElementAt(i) + "</label><br />");
}

Upvotes: 0

Fredrik M&#246;rk
Fredrik M&#246;rk

Reputation: 158369

I assume that values and labels contain an equal amount of values and that that they are sorted in a way that the first value corresponds to the first label and so on. If that is the case you can probably get an enumerator for each of the IEnumerable<string> objects and iterate over the collections using the enumerators. Also, you can add an int variable that you increment for each iteration and use it for creating unique id's:

public static string CheckBoxList(this HtmlHelper htmlhelper, IEnumerable<string> values, IEnumerable<string> labels, string name, IDictionary<string, object> HtmlAttributes)
{
    if (labels == null)
        return "";

    StringBuilder sb = new StringBuilder();
    string[] modelValues = new string[] { };
    ModelState modelState;

    if (htmlhelper.ViewData.ModelState.TryGetValue(name, out modelState))
    {
        modelValues = ((string[])modelState.Value.RawValue);
    }

    IEnumerator<string> valueEnumerator = values.GetEnumerator();
    IEnumerator<string> labelEnumerator = labels.GetEnumerator();
    int index = 0;
    while (valueEnumerator.MoveNext() && labelEnumerator.MoveNext())
    {
        bool isChecked = modelValues.Contains(valueEnumerator.Current);
        sb.Append(CreateCheckBox(name, valueEnumerator.Current, isChecked, HtmlAttributes));
        sb.Append(string.Format(" <label for=\"{0}\" id=\"label-{1}\">{2}</label></br>", name, index, labelEnumerator.Current);
        index++;
    }

    return sb.ToString();
}

Upvotes: 2

Related Questions