Hi, 2012/6/28 David Muir <davidkm...@gmail.com>
> I'd assume that array_map() only works with arrays, while list > comprehension should work with anything traversable. > That sounds more like a "bug" (better: "Missing feature") in array_map() and less a missing language feature... Regards, Sebastian > > David > > > On 28/06/2012, at 10:43 PM, Sebastian Krebs <krebs....@gmail.com> wrote: > > > Hi, > > > > Whats the difference to the (already existing) function array_map() > (except > > the syntax and one more new keyword)? > > > >> $firstNames = array_map(function($user){return $user->firstname;}, > > $users); > > > > Don't want to rewrite every example you gave, but you probably see my > point. > > > > Regards, > > Sebastian > > > > 2012/6/28 Nikita Popov <nikita....@gmail.com> > > > >> Hi internals! > >> > >> Python and several other languages include support for list > >> comprehensions and generator expressions and I'd like to see something > >> similar in PHP too. > >> > >> I created a hacky proof of concept implementation here: > >> https://github.com/nikic/php-src/tree/addListComprehensions. It's > >> really dirty, but it implements both features in about ~150 lines of > >> code. > >> > >> Currently I'm using the following syntax: > >> > >> $firstNames = [foreach ($users as $user) yield $user->firstName]; > >> > >> This code is roughly equivalent to writing: > >> > >> $firstNames = []; > >> foreach ($users as $user) { > >> $firstNames[] = $user->firstName; > >> } > >> > >> You may notice that this particular list comprehension provides the > >> same functionality as array_column(), just in a little more > >> generalized way. E.g. you could use all of the following without > >> having special functions for them all: > >> > >> $firstNames = [foreach ($users as $user) yield $user->firstName]; > >> > >> $firstNames = [foreach ($users as $user) yield $user->getFirstName()]; > >> > >> $firstNames = [foreach ($users as $user) yield $user['firstName']]; > >> > >> It's also possible to explicitly specify a key: > >> > >> $firstNames = [foreach ($users as $user) yield $user->id => > >> $user->firstName]; > >> > >> It is also possible to filter elements using list comprehensions: > >> > >> $underageUsers = [foreach ($users as $user) if ($user->age < 18) > >> yield $user]; > >> // or just the names > >> $underageUserNames = [foreach ($users as $user) if ($user->age < > >> 18) yield $user->firstName]; > >> > >> It is also possible to nest multiple foreach loops: > >> > >> $aList = ['A', 'B']; > >> $bList = [1, 2]; > >> $combinations = [foreach ($aList as $a) foreach ($bList as $b) > >> yield [$a, $b]]; > >> // gives: [ ['A', 1], ['A', 2], ['B', 1], ['B', 2] ] > >> > >> All the above are list comprehensions (or in PHP rather array > >> comprehensions), i.e. they create an array as the result. > >> > >> If this is not needed it is also possible to compute the values lazily > >> using generator expressions, which use () instead of []. > >> > >> $firstNames = (foreach ($users as $user) yield $user->firstName); > >> > >> In this case $firstNames will no longer be an array of first names, > >> but instead will be a generator producing first names. > >> > >> This is handy if you only need to iterate the resulting "list" only > >> once as it saves you holding the whole list in memory. > >> > >> Also it allows you to work with infinite lists easily: > >> > >> function *naturalNumbers() { > >> for ($i = 0; ; ++$i) { > >> yield $i; > >> } > >> } > >> > >> // all natural numbers > >> $numbers = naturalNumbers(); > >> // only the odd ones > >> $oddNumbers = (foreach ($numbers as $n) if ($n % 2) yield $n); > >> // ... > >> > >> (At this point I wonder whether one should include support for > >> for-loops in list comprehensions. So the naturalNumbers() function > >> could be replaced with (for ($i = 0;; ++$i) yield $i), etc) > >> > >> So, what do you think? Do we want something like this in PHP? > >> > >> Nikita > >> > >> -- > >> PHP Internals - PHP Runtime Development Mailing List > >> To unsubscribe, visit: http://www.php.net/unsub.php > >> > >> >