How to iterate over objects indexed by a domain in Chapel

97 Views Asked by At

I have a set of objects var Players: [domain] Player and I'd like to iterate over the objects in reverse order. Something like

This works

for p in Players by {
   writeln(p.name);
   writeln("I was the %i st player added".format(p.pid)")  // pid corresponds to domain index.
   p.shoeSize = 1.5*p.shoeSize
}

But!

// poops
for p in Players by -1 {
   writeln(p.name);
   writeln("I was the %i -to-last player added".format(p.pid)")  // pid corresponds to domain index.
   p.shoeSize = 1.5*p.shoeSize
}

And I want to make sure the shoe size updates.

== UPDATE ==

Some additional information / specs to honor @bencray's request

class Player {
  var name: string,
      position: string,
      pid: int,
      shoeSize: int;
}

var playerDom = {1..0},
    players: [playerDom] Player;

writeln("I have %i players".format(playerDom.size));
// Now add some players
// Better way to increase as I go along?
playerDom = {1..playerDom.size+1};
players[playerDom.size] = new Player(name="Gretsky", position="Center", shoeSize=10, pid=playerDom.size);
writeln("I have %i players".format(playerDom.size));

playerDom = {1..playerDom.size+1};
players[playerDom.size] = new Player(name="Blake", position="Defenseman", shoeSize=12, pid=playerDom.size);
writeln("I have %i players".format(playerDom.size));

for p in players {
  writeln("Player %i has shoeSize %i".format(p.pid, p.shoeSize));
  p.shoeSize += 1;
}

for p in players {
  writeln("Player NOW %i has shoeSize %i".format(p.pid, p.shoeSize));
}

// poops during compilation
// domobj.chpl:31: error: the first argument of the 'by' operator is not a range
for p in players by -1 {
  writeln("Player NOW %i has shoeSize %i".format(p.pid, p.shoeSize));
}
1

There are 1 best solutions below

1
On BEST ANSWER

The range operation by does not work on arrays like you had hoped. Instead, we are left with the slightly less elegant form of iterating over the reversed indices as shown here:

for i in players.domain by -1 {
  writeln("Player NOW %i has shoeSize %i".format(players[i].pid, players[i].shoeSize));
}

Below is your larger code-block with some other cleanups:

var playerDom = {1..0},
    players: [playerDom] Player;

writeln("I have %i players".format(playerDom.size));
players.push_back(new Player(name="Gretsky", position="Center", shoeSize=10, pid=players.size+1));
writeln("I have %i players".format(playerDom.size));
players.push_back(new Player(name="Blake", position="Defenseman", shoeSize=12, pid=players.size+1));
writeln("I have %i players".format(playerDom.size));

for p in players {
  writeln("Player %i has shoeSize %i".format(p.pid, p.shoeSize));
  p.shoeSize += 1;
}

for p in players {
  writeln("Player NOW %i has shoeSize %i".format(p.pid, p.shoeSize));
}

for i in players.domain by -1 {
  ref p = players[i];
  writeln("Player NOW %i has shoeSize %i".format(p.pid, p.shoeSize));
}

class Player {
  var name: string,
      position: string,
      pid: int,
      shoeSize: int;
}