codecamp

hack集合:Iterating

集合通过迭代(Iterating)foreach

<?hh

namespace Hack\UserDocumentation\Collections\Iterating\Examples\FEach;

function run(): void {
  $vec = Vector {'A', 'B', 'C'};
  $map = Map {'A' => 1, 'B' => 2};
  $set = Set {800, 900, 1000};
  $pair = Pair {'A', 'B'};

  foreach ($vec as $val) {
    var_dump($val);
  }

  foreach ($map as $key => $val) {
    var_dump($key);
    var_dump($val);
  }

  foreach ($set as $val) {
    var_dump($val);
  }

  foreach ($pair as $key => $val) {
    var_dump($key);
    var_dump($val);
  }
}

run();

Output

string(1) "A"
string(1) "B"
string(1) "C"
string(1) "A"
int(1)
string(1) "B"
int(2)
int(800)
int(900)
int(1000)
int(0)
string(1) "A"
int(1)
string(1) "B"

注意事项

当使用它foreach来迭代集合时,有几点值得注意的注意事项。

修改集合

不允许从集合添加或删除项目,如果尝试,将导致一个InvalidOperationException。

<?hh

namespace Hack\UserDocumentation\Collections\Iterating\Examples\Modifying;

function run(): void {
  $vec = Vector {'A', 'B', 'C'};

  try {
    foreach ($vec as $val) {
      if ($val === 'B') {
        // This will actually be allowed, but the next time through the loop
        // the InvalidOperationException will be thrown.
        $vec[] = 'D';
      }
      var_dump($vec);
      var_dump($val);
    }
  } catch (\InvalidOperationException $ex) {
    var_dump($ex->getMessage());
  }

  $set = Set {100, 200, 300};

  try {
    foreach ($set as $val) {
      if ($val === 300) {
        // This will actually be allowed, and even though this is the last
        // element in the set, we actually do the check in the foreach again so
        // the InvalidOperationException will be thrown.
        $set->remove(300);
      }
      var_dump($set);
      var_dump($val);
    }
  } catch (\InvalidOperationException $ex) {
    var_dump($ex->getMessage());
  }
}

run();

Output

object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "A"
object(HH\Vector)#1 (4) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
  [3]=>
  string(1) "D"
}
string(1) "B"
string(40) "Collection was modified during iteration"
object(HH\Set)#3 (3) {
  int(100)
  int(200)
  int(300)
}
int(100)
object(HH\Set)#3 (3) {
  int(100)
  int(200)
  int(300)
}
int(200)
object(HH\Set)#3 (2) {
  int(100)
  int(200)
}
int(300)
string(40) "Collection was modified during iteration"

请注意,在该示例中,实际的添加或删除将生效,但是当我们回到循环迭代检查时将抛出异常。

参考

您不能通过foreach引用作为集合。

foreach ($vec as &$val)

这将导致致命的错误,甚至不是例外。

有一种模拟这种行为的方法。

<?hh

namespace Hack\UserDocumentation\Collections\Iterating\Examples\Reference;

function run(): void {
  $arr = array ('A', 'B', 'C');
  // if $arr was a Vector instead, we would get a
  // Fatal error: Collection elements cannot be taken by reference
  var_dump($arr);
  foreach ($arr as &$val) {
    var_dump($val);
    if ($val === 'B') {
      $val = 'D';
    }
    var_dump($arr);
  }

  // How to mimic the above
  $vec = Vector {'A', 'B', 'C'};
  var_dump($vec);
  foreach ($vec as $key => $val) {
    var_dump($val);
    if ($val === 'B') {
      $vec[$key] = 'D';
    }
    var_dump($vec);
  }
}

run();

Output

array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "A"
array(3) {
  [0]=>
  &string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "B"
array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  &string(1) "D"
  [2]=>
  string(1) "C"
}
string(1) "C"
array(3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "D"
  [2]=>
  &string(1) "C"
}
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "A"
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "C"
}
string(1) "B"
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "D"
  [2]=>
  string(1) "C"
}
string(1) "C"
object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "D"
  [2]=>
  string(1) "C"
}

基本上,您明确拉出集合的键/值对,然后显式修改键的值。

hack集合:Read Write
hack集合:Compared To Arrays
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }