post
poster: Jaguarstrike
description: Arrays with closure mappable/selectable values done right
language: PHP
[download]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
class ExArray extends ArrayObject
{
    public function select($closure)
    {
        $exArray  = new ExArray();
        
        foreach($this->getArrayCopy() as $k => $v)
        {
            if($closure($v,$k))
            {
                $exArray[$k] = $v;
            }
        }
        
        return $exArray;
    }
    
    public function map($closure)
    /**
      Function maps arrays to arrays as follows:
      If a scalar or many-element array is returned
      by the closure then the keys are preserved and
      the new pair is put in place of the original.
    
      If the closure returns an array with a single
      key/value pair, then the new key for the pair
      will be taken from the new array, as will the
      value. This behavior can be overridden by
      returning the following structure:
      array($new_key => array('x'=>'y'));
    */
    {
        $exArray  = new ExArray();
        
        foreach($this->getArrayCopy() as $k => $v)
        {
            $elem = $closure($v,$k);
            
            if(is_array($elem) && count($elem) == 1)
            {
                $new_key = array_shift(array_keys($elem));
                
                $new_val = array_shift($elem);
            }
            else
            {
                $new_key = $k;
                $new_val = $elem;
            }
            
            $exArray[$new_key] = $new_val;
        }
        
        return $exArray;
    }
    
    public function __call($name,$args)
    {
        $result = call_user_func_array($name, array_merge(array($this->getArrayCopy()), $args));

        if(is_array($result))
        {
            return new ExArray($result);
        }
        else
        {
            return $result;
        }
    }
    
    public function __toString()
    {
        return implode("\t", $this->getArrayCopy());
    }
    
    public function __invoke()
    {
        $args = func_get_args();
        
        if(count($args) == 0)
        {
            return $this->__toArray();
        }
        else
        {
            return $this->offsetGet($args[0]);
        }
    }
    
    public function __toArray()
    {
        return $this->getArrayCopy();
    }
}