Jump to content

PageArray->map


Martin Muzatko
 Share

Recommended Posts

Hello there!

I'd love to see more array operation functions such as map/reduce. There are already a few helpful functions there like pop, shift, etc.

I find myself turning pageArrays into arrays, do array_map or similar and create pageArrays again from that data.

For Processwire, it would be really helpful to perform forEach operations more comfortably.

E.g.

<?php
$allTitles = $pages->map(function($page){return $page->title});

// vs traditionally:

$allTitles = [];
foreach($pages as $page) {
	array_push($allTitles, $page->title);
}

$pages->reduce would be really helpful too. This would avoid many in-between variables when calculating sums of fields stored in individual pages.

 

Thank you in advance :)

Best,
Martin

  • Like 1
Link to comment
Share on other sites

what about this?

<?php
$allTitles = $yourPageArray->each('title');

// or if it was more complex
$allTitles = $yourPageArray->each(function($page) {
  return "{$page->forename} {$page->surname}";
}

you can also add your own methods via hooks:

  $wire->addHookMethod('WireArray::test', function($event) {
    $arr = $event->object;
    $out = [];
    foreach($arr as $item) $out[] = 'testing page ' . $item->id;
    $event->return = $out;
  });

59b6439d01eb4_2017-09-1110_03_51-EditPage_Testhrd-360-neu_Chakaaa!360.hrdiamonds_com.png.c65551ea834c3c4879a354c5125442dc.png

  • Like 3
Link to comment
Share on other sites

Here are my generic versions

WireArray::map

wire()->addHookMethod('WireArray::map', function (HookEvent $e) {
    $func = $e->arguments(0);
    if (!is_callable($func)) throw new WireException('first argument must be a callable function');

    $mapped = array_map($func, $e->object->getArray());
    $e->return = $mapped;
});

WireArray::reduce

wire()->addHookMethod('WireArray::reduce', function (HookEvent $e) {
    $func = $e->arguments(0);
    $initial = $e->arguments(1) ?? [];
    if (!is_callable($func)) throw new WireException('first argument must be a callable function');

    $reduced = array_reduce($e->object->getArray(), $func, $initial);
    $e->return = $reduced;
});

WireArray::forEach

wire()->addHookMethod('WireArray::forEach', function (HookEvent $e) {
    $func = $e->arguments(0);
    if (!is_callable($func)) throw new WireException('first argument must be a callable function');

    $foreached = [];
    foreach ($e->object as $i => $item) $foreached[] = $func($item, $i);
    $e->return = $foreached;
});

Tests

$mapped = $pages->find('id>0, parent=2')->map(function($page) {
    return [
        'title' => $page->title,
        'id' => $page->id
    ];
});

$reduced = $pages->find('template=post')->reduce(function($carry, $item){
    $carry[] = $item->id;
    return $carry;
}, []);

$foreached = $pages->find('template=post')->forEach(function($item){
    echo $item->id . '<br>';
});

dump($mapped);
dump($reduced);
dump($foreached);

Which outputs

array (4)
    0 => array (2)
        title => "Pages" (5)
        id => 3
    1 => array (2)
        title => "Setup" (5)
        id => 22
    2 => array (2)
        title => "Modules" (7)
        id => 21
    3 => array (2)
        title => "Access" (6)
        id => 28

array (8)
    0 => 1024
    1 => 1026
    2 => 1028
    3 => 1031
    4 => 1033
    5 => 1058
    6 => 1062
    7 => 1065

1024
1026
1028
1031
1033
1058
1062
1065

array (8)
    0 => null
    1 => null
    2 => null
    3 => null
    4 => null
    5 => null
    6 => null
    7 => null
    
29.59ms, 0.06MB

 

  • Like 5
Link to comment
Share on other sites

  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...