Używam mapy w php w następujący sposób:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
Czy można uzyskać indeks wartości w funkcji?
Ponadto - jeśli piszę kod, który wymaga indeksu, czy powinienem używać pętli for zamiast mapy?
array_map()
dowolną liczbę argumentów :)array_keys
pozostaną w tej samej kolejności, co w oryginalnej tablicy. W związku z tym możesz skończyć mapowaniem kluczy na złe wartości. Bezpiecznym podejściem jest użycie tylkoarray_keys
drugiego argumentu polecenia,array_map
a następnie przekazanie tablicy do zamknięcia za pomocąuse
instrukcji.Podczas mapowania anonimowej funkcji na anonimową tablicę nie ma możliwości uzyskania dostępu do kluczy:
array_map( function($val) use ($foo) { /* ... */ }, array(key1 => val1, key2 => val2, /* ... */));
array_reduce również nie ma dostępu do kluczy. array_walk może uzyskać dostęp do kluczy, ale tablica jest przekazywana przez odwołanie, co wymaga warstwy pośredniej.
Oto niektóre rozwiązania:
Tablica par
To źle, ponieważ zmieniamy oryginalną tablicę. Dodatkowo wywołania „array ()” na poziomie standardowym rosną liniowo wraz z długością tablicy:
array_map( function($pair) use ($foo) { list($key, $val) = $pair; /* ... */ }, array(array(key1, val1), array(key2, val2), /* ... */));
Zmienna tymczasowa
Działamy na oryginalnej tablicy, a schemat standardowy jest stały, ale możemy łatwo przebić istniejącą zmienną:
$i_hope_this_does_not_conflict = array(key1 => val1, key2 => val2, /* ... */); array_map( function($key, $val) use ($foo) { /* ... */ }, array_keys($i_hope_this_does_not_conflict), $i_hope_this_does_not_conflict); unset($i_hope_this_does_not_conflict);
Funkcja jednorazowego użytku
Możemy użyć zakresu funkcji, aby zapobiec przebijaniu istniejących nazw, ale musimy dodać dodatkową warstwę „użytkowania”:
call_user_func( function($arr) use ($foo) { return array_map(function($key, $val) use ($foo) { /* ... */ }, array_keys($arr), $arr); }, array(key1 => val1, key2 => val2, /* ... */));
Wieloargumentowa funkcja jednorazowa
Definiujemy funkcję, którą mapujemy w oryginalnym zakresie, aby zapobiec użyciu schematu „użyj”):
call_user_func( function($f, $arr) { return array_map($f, array_keys($arr), $arr); }, function($key, $val) use ($foo) { /* ... */ }, array(key1 => val1, key2 => val2, /* ... */));
Nowa funkcja
Warto zauważyć, że nasza ostatnia jednorazowa funkcja ma ładny, ogólny podpis i wygląda bardzo podobnie do tablicy array_map. Możemy chcieć nadać temu nazwę i użyć go ponownie:
function array_mapk($f, $arr) { return array_map($f, array_keys($arr), $arr); }
Nasz kod aplikacji staje się wtedy:
array_mapk( function($key, $val) use ($foo) { /* ... */ }, array(key1 => val1, key2 => val2, /* ... */));
Pośredni spacer po szyku
Pisząc powyższe, zignorowałem array_walk, ponieważ wymaga ona przekazania argumentu przez referencję; jednak od tego czasu zdałem sobie sprawę, że można łatwo obejść ten problem za pomocą call_user_func. Myślę, że to jak dotąd najlepsza wersja:
call_user_func( 'array_walk', array(key1 => val1, key2 => val2, /* ... */), function($val, $key) use ($foo) { /* ... */ });
źródło
Bardzo proste:
Tylko funkcja array_map: nie ma klucza indeksu!
$params = [4,6,2,11,20]; $data = array_map(function($v) { return ":id{$v}";}, $params); array (size=5) 0 => string ':id4' (length=4) 1 => string ':id6' (length=4) 2 => string ':id2' (length=4) 3 => string ':id11' (length=5) 4 => string ':id20' (length=5)
Teraz połącz z array_keys:
$data = array_map( function($k) use ($params) { return ":id{$k}_${params[$k]}"; }, array_keys($params) ); array (size=5) 0 => string ':id0_4' (length=6) 1 => string ':id1_6' (length=6) 2 => string ':id2_2' (length=6) 3 => string ':id3_11' (length=7) 4 => string ':id4_20' (length=7)
źródło
Możesz stworzyć własną funkcję mapy za pomocą
foreach
:<?php function myCallback($key, $val) { var_dump("myCallback - key: $key, val: $val"); return $val * 2; } function foreachMap($callback, $givenArray) { $result = []; foreach ($givenArray as $key=>$val) { $result[$key] = $callback($key, $val); } return $result; } $values = array(4, 6, 3); $mapped = foreachMap('myCallback', $values); var_dump($mapped);
spróbuj: https://3v4l.org/pmFlB
źródło