Ordinal numbers in foreach loops (not a question)

Avernite

Member
Joined
Jan 17, 2023
Messages
18
Programming Experience
10+
It would be nice to (optionally) have access to ordinal numbers in foreach loops.

For example, printing an enumerated list of names:

C#:
foreach (string name in names ord as n)
  Debug.Log(string.Format("{0}. {1}", n + 1, name));

The keyword 'ord' starts at 0 and increments by 1 per iteration. It requires an alias for resolving ambiguity in nested foreach loops.

Use of 'ord' is known at compile time, so no concerns about extra overhead in foreach loops that don't reference it.

Also, using 'ord' for array initialization:

C#:
int[] ints = int[12];
foreach (int in ints ord as n) // initialize to {1..12}
  value = n + 1; // value is write-only here

Instead of:

C#:
int[] ints = int[12];
for (int i = 0; i < ints.Length; i++) // initialize to {1..12}
  ints[i] = i + 1;
 
Last edited:
Several Linq methods has index available, here is one example with Select:
C#:
string[] items = { "A", "B", "C" };
var indexedItems = items.Select((item, index) => (item, index));
foreach (var (item, index) in indexedItems)
{
    Console.WriteLine($"{item} has index {index}");
}
To generate a range of ints and convert to array one could do:
C#:
var ints = Enumerable.Range(1, 12).ToArray();
 
Very interesting. I didn't know this existed, thank you.

Linq offers what I've been thinking about lately, namely a concise way to perform queries on collections using a 'where' clause.

Something like this:

C#:
// Assume persons is an array of Person, containing some elements of the PoliceOfficer class (which is a superclass of Person)

// Obtain all minors
Person[] minors = persons where age < 18; // age is a member of Person class

// Obtain all 'rookie' PoliceOfficer[s] (the 'element' keyword is introduced here to represent anonymous collection elements as they are examined)
PoliceOfficer[] rookies = persons where element is PoliceOfficer && (element as PoliceOfficer).YearsOfService < 1;

// Print out years of service for all retiring PoliceOfficer[s] (age 60 or older):
foreach (officer as PoliceOfficer in persons where officer.age >= 60) // Filtering for PoliceOfficer is implied by 'as PoliceOfficer'
  Debug.Log("{0}: {1}", officer.name, officer.YearsOfService);
 
Even before Linq you could do

C#:
var i = 0;
foreach(var x in y){
  //...
  i++;
}

But if your collection is indexable just use a for loop

C#:
for(int i = 0; i < some.Length; i++){
  var x = y[i];
}
 
Fixed:

C#:
// Assume persons is an array of Person, containing some elements of the PoliceOfficer class (which is a subclass of Person)

// Obtain all minors
Person[] minors = persons.Where(p => p.age < 18).ToArray();

// Obtain all 'rookie' PoliceOfficer[s] (the 'element' keyword is introduced here to represent anonymous collection elements as they are examined)
PoliceOfficer[] rookies = persons.OfType<PoliceOfficer>().Where(po  => po.YearsOfService < 1).ToArray();

// Print out years of service for all retiring PoliceOfficer[s] (age 60 or older):
foreach (var officer in  persons.OfType<PoliceOfficer>().Where(po  => po.age >= 60))
  Debug.Log("{0}: {1}", officer.name, officer.YearsOfService);
 
I think it depends on your definition of "like" - seems to me that none of your lines of code would work: is it pseudo code?

It is theoretical "wish" code where collection queries are more tightly integrated into the language.

(Note that I flipped PoliceOfficer to be a subclass of Person, not a parent class of it)

Yes, that is the correct term, thank you.
 
Back
Top Bottom