Error Cannot implicitly convert type 'string' to 'int' - for the iterator in a ForEach loop

2.3k Views Asked by At

My code posted below, does not run, due to an

Error - Cannot implicitly convert type 'string' to 'int'

This error occurs to the iterator i within both my if conditions.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MaleOrFemale
{
    class Program
    {
        static void Main(string[] args)
        {
            string[,] names = new string [7,2] {{"Cheryl Cole","F"},{"Hilary Clinton","F"},{"Noel Gallagher","M"},{"David Cameron","M"},{"Madonna","F"},{"Sergio Aguero","M"},{"Sheik Mansour","M"}};
            int mCount = 0;
            int fCount = 0;


            foreach ( var i in names)
            {
                if (names[i,1]== "M")
                {
                    mCount += 1;  
                }
                else if (names[i,1]=="F")
                {
                    fCount += 1;
                }
            }

            Console.WriteLine("mCount = {0}", mCount);
            Console.WriteLine("fCount = {0}", fCount);
            Console.Read();


        }
    }
}

Why can my array index not use the foreach Iterator in this case?

7

There are 7 best solutions below

6
On BEST ANSWER

You are trying to access the array via indexes, indexes are meant to be integers.

Here when you call names[i,1], then i should be integer not string. When you have foreach ( var i in names) then i is inferred to be string because name is array of type string[,].

If you want to access each element via index try using a for loop instead

for(var i = 0; i < names.GetLength(0); i++)
{
    if (names[i,1]== "M")
    {
        mCount += 1;  
    }
    else if (names[i,1]=="F")
    {
        fCount += 1;
    }
 }

Keep in mind that when you use foreach you are accessing elements not the indexes.

But best way here is to define a class instead of holding data into multi-dimensional arrays.

public class Person
{
    public string Name { get; set; }
    public Gender Gender { get; set; }
}

public enum Gender
{
    Male,
    Female
}

and the program will looks like this

var people = new List<Person>();
people.Add(new Person(){ Name = "Cheryl Cole", Gender = Gender.Female });
people.Add(new Person(){ Name = "Hilary Clinton", Gender = Gender.Female });
people.Add(new Person(){ Name = "Noel Gallagher", Gender = Gender.Male });
int mCount = 0;
int fCount = 0;

foreach (var person in people)
{
    if (person.Gender == Gender.Male)
        mCount += 1;
    else if (person.Gender == Gender.Female)
        fCount += 1;
}

Console.WriteLine("mCount = {0}", mCount);
Console.WriteLine("fCount = {0}", fCount);
Console.Read();

or you can use linq for the whole concept of counting items with specific conditions

Console.WriteLine("#Male = {0}", people.Count(x=>x.Gender == Gender.Male));
Console.WriteLine("#Female = {0}", people.Count(x=>x.Gender==Gender.Female));
0
On

var i dose not contain int value. So cannot access like this names[i,1].So your implementation should be changed like as follows.

        foreach ( var i in names){
            if (i[1] == "M"){
                mCount++;  
            }
            else if (i[1] == "F"){
                fCount++;
            }
        }
0
On

Your iterator will return an array, not an int.

Try something like this:

        foreach ( var i in names)
        {
            if (i[1]== "M")
            {
                mCount += 1;  
            }
            else if (i[1]=="F")
            {
                fCount += 1;
            }
        }

Although as others mentioned, this is a sloppy way of doing it. Better to use structs and/or custom classes and/or enums.

0
On

For your particular case, there is no need for foreach loop, foreach will iterate each element in your multi-dimensional array and return each element one by one. That is why you are getting the error. Since i will be string value on each iteration and you are trying to use it in array index, which can only accept an integer value.

You can fix this by using a simple for loop like:

for (var i = 0; i < names.GetLength(0); i++)
{
    if (names[i, 1] == "M")
    {
        mCount += 1;
    }
    else if (names[i, 1] == "F")
    {
        fCount += 1;
    }
}

Notice the GetLength method, it will return the length of specified dimension.


But a better option would be to use a class for your data, instead of multi-dimensional array, and even an enum for gender.

public class MyDataClass
{
    public string Name { get; set; }
    public Gender Gender { get; set; }
}

public enum Gender
{
    Male, 
    Female,
    Other,
}

And then you can do:

List<MyDataClass> list = new List<MyDataClass>
{
    new MyDataClass {Name = "Cheryl Cole", Gender = Gender.Female},
    new MyDataClass {Name = "Hilary Clinton", Gender = Gender.Female},
    new MyDataClass {Name = "Noel Gallagher", Gender = Gender.Female},
    new MyDataClass {Name = "David Cameron", Gender = Gender.Male},
    new MyDataClass {Name = "Madonna", Gender = Gender.Female},
    new MyDataClass {Name = "Sergio Aguero", Gender = Gender.Male},
    new MyDataClass {Name = "Sheik Mansour", Gender = Gender.Male},

};

foreach (var item in list)
{
    if (item.Gender == Gender.Male)
        mCount += 1;
    if (item.Gender == Gender.Female)
        fCount += 1;
}
0
On

At compile-time, the variable i is determined as a String. So using the foreach iterator isn't going to work with your current implementation.

Alternatively, you can use the for iterator with the following code:

string[,] names = new string[7, 2] { { "Cheryl Cole", "F" }, { "Hilary Clinton", "F" }, { "Noel Gallagher", "M" }, { "David Cameron", "M" }, { "Madonna", "F" }, { "Sergio Aguero", "M" }, { "Sheik Mansour", "M" } };
int mCount = 0;
int fCount = 0;

int length = names.GetLength(0);

for (int i = 0; i < length; i++)
{
    if (names[i, 1] == "M")
    {
        mCount += 1;
    }
    else if (names[i, 1] == "F")
    {
        fCount += 1;
    }
}

Console.WriteLine("mCount = {0}", mCount);
Console.WriteLine("fCount = {0}", fCount);
Console.Read();

which outputs:

mCount = 4
fCount = 3

The above code uses names.GetLength(0); in order to get the length of the array at dimension 0. In our case, this outputs 7.

0
On

Since you are using foreach to loop, your counter variable (i) is being set to a string (value) from the array... Use a for loop instead... for(int i=0; i< names.GetLength(0);i++)

0
On

You should explore the option of using classes and LINQ to make the code cleaner and maintainable.

using System;
using System.Collections.Generic;
using System.Linq;

public enum Gender
{
    Female, Male
}

public class Person
{
    public string Name { get; private set; }
    public Gender Gender { get; private set; }

    public Person(string name, Gender gender)
    {
        Name = name;
        Gender = gender;
    }
}

public class Program
{
    public static void Main()
    {
        var persons = new[] { new Person("Cheryl Cole", Gender.Female), new Person("David Cameron", Gender.Male) };

        var mCount = persons.Count(p => p.Gender == Gender.Male);
        var fCount = persons.Count(p => p.Gender == Gender.Female);

        Console.WriteLine("mCount = {0}", mCount);
        Console.WriteLine("fCount = {0}", fCount);
    }
}