user3522950
user3522950

Reputation: 61

How do I make the foreach instruction iterate in 2 places?

how do I make the foreach instruction iterate both in the "files" variable and in the "names" array?

var files = Directory.GetFiles(@".\GalleryImages");
string[] names = new string[8] { "Matt", "Joanne", "Robert","Andrei","Mihai","Radu","Ionica","Vasile"};

I've tried 2 options.. the first one gives me lots of errors and the second one displays 8 images of each kind

foreach(var file in files,var i in names)
{
//Do stuff
}

and

foreach(var file in files)
{
   foreach (var i in names)
    { 
     //Do stuff
    }
 }

Upvotes: 0

Views: 115

Answers (6)

nikeee
nikeee

Reputation: 10724

You can try using the Zip Extension method of LINQ:

 int[] numbers = { 1, 2, 3, 4 };
 string[] words = { "one", "two", "three" };

 var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second);

 foreach (var item in numbersAndWords)
    Console.WriteLine(item);

Would look something like this:

 var files = Directory.GetFiles(@".\GalleryImages");
 string[] names = new string[] { "Matt", "Joanne", "Robert", "Andrei", "Mihai","Radu","Ionica","Vasile"};
 var zipped = files.Zip(names, (f, n) => new { File = f, Name = n });
 foreach(var fn in zipped)
     Console.WriteLine(fn.File + " " + fn.Name);

But I haven't tested this one.

Upvotes: 5

Michael Edenfield
Michael Edenfield

Reputation: 28338

You have two options here; the first works if you are iterating over something that has an indexer, like an array or List, in which case use a simple for loop and access things by index:

for (int i = 0; i < files.Length && i < names.Length; i++)
{
  var file = files[i];
  var name = names[i];

  // Do stuff with names.
}

If you have a collection that doesn't have an indexer, e.g. you just have an IEnumerable and you don't know what it is, you can use the IEnumerable interface directly. Behind the scenes, that's all foreach is doing, it just hides the slightly messier syntax. That would look like:

var filesEnum = files.GetEnumerator();
var namesEnum = names.GetEnumerator();

while (filesEnum.MoveNext() && namesEnum.MoveNext())
{

  var file = filesEnum.Current;
  var name = namesEnum.Current;

  // Do stuff with files and names.
}

Both of these assume that both collections have the same number of items. The for loop will only iterate as many times as the smaller one, and the smaller enumerator will return false from MoveNext when it runs out of items. If one collection is bigger than the other, the 'extra' items won't get processed, and you'll need to figure out what to do with them.

Upvotes: 1

qqbenq
qqbenq

Reputation: 10460

You can try something like this:

var pairs = files.Zip(names, (f,n) => new {File=f, Name=n});
foreach (var item in pairs)
{
    Console.Write(item.File);
    Console.Write(item.Name);
}

Upvotes: 0

Fuzzyma
Fuzzyma

Reputation: 8484

I guess the files array and the names array have the same indices. When this is the case AND you always want the same index at one time you do this:

for (int key = 0; key < files.Length; ++key)
{
  // access names[key] and files[key] here
}

Upvotes: 0

Peter Ritchie
Peter Ritchie

Reputation: 35869

It's not clear what you're asking. But, you can't iterate two iterators with foreach; but you can increment another variable in the foreach body:

int i = 0;
foreach(var file in files)
{
   var name = names[i++];
   // TODO: do something with name and file
}

This, of course, assumes that files and names are of the same length.

Upvotes: 1

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101701

You can't. Use a for loop instead.

for(int i = 0; i < files.Length; i++)
{
   var file = files[i];
   var name = names[i];
}

If the both array have the same length this should work.

Upvotes: 1

Related Questions