Tag Archives: underscore

Underscore.php Mixin: multisort

<?php
    __()->mixin([
        "reindex" => function ($items, $indices) {
            return __($indices)->map(function ($index) use ($items) { return $items[$index]; });
        },
        
        "multisort" => function ($items, $keys) {
            if (count($items) <= 1) {
                return $items;
            }
            $__items = __($items);
            $args = [];
            foreach ($keys as $key) {
                if (!is_array($key)) {
                    $key = [$key];
                }
                $property = array_shift($key);
                $args[] = $__items->pluck($property);
                $args = array_merge($args, $key);
            }
            $indices = __()->range($__items->size());
            $args[] = &$indices;
            call_user_func_array("array_multisort", $args);
            return $__items->reindex($indices);
        }
    ]);
    
    function format($president) {
        return sprintf(
            "%d: %s %s (%s)",
            $president["order"],
            $president["firstName"],
            $president["lastName"],
            $president["party"]);
    }
    
    function display($presidents) {
        print_r(__($presidents)->invoke("format"));
    }
    
    $presidents = __([
        ["order" => 1, "firstName" => "George", "lastName" => "Washington", "party" => "None"],
        ["order" => 2, "firstName" => "John", "lastName" => "Adams", "party" => "Federalist"],
        ["order" => 3, "firstName" => "Thomas", "lastName" => "Jefferson", "party" => "Democratic-Republican"],
        ["order" => 4, "firstName" => "James", "lastName" => "Madison", "party" => "Democratic-Republican"],
        ["order" => 5, "firstName" => "James", "lastName" => "Monroe", "party" => "Democratic-Republican"],
        ["order" => 6, "firstName" => "John Quincy", "lastName" => "Adams", "party" => "Democratic-Republican"],
        ["order" => 7, "firstName" => "Andrew", "lastName" => "Jackson", "party" => "Democratic"],
        ["order" => 8, "firstName" => "Martin", "lastName" => "Van Buren", "party" => "Democratic"],
        ["order" => 9, "firstName" => "William Henry", "lastName" => "Harrison", "party" => "Whig"],
        ["order" => 10, "firstName" => "John", "lastName" => "Tyler", "party" => "Whig"]
    ]);
    
    display($presidents->multisort(["firstName"]));
    display($presidents->multisort([["lastName", SORT_DESC]]));
    display($presidents->multisort(["party", ["order", SORT_DESC]]));
?>

Output:

Array
(
    [0] => 7: Andrew Jackson (Democratic)
    [1] => 1: George Washington (None)
    [2] => 4: James Madison (Democratic-Republican)
    [3] => 5: James Monroe (Democratic-Republican)
    [4] => 2: John Adams (Federalist)
    [5] => 10: John Tyler (Whig)
    [6] => 6: John Quincy Adams (Democratic-Republican)
    [7] => 8: Martin Van Buren (Democratic)
    [8] => 3: Thomas Jefferson (Democratic-Republican)
    [9] => 9: William Henry Harrison (Whig)
)
Array
(
    [0] => 1: George Washington (None)
    [1] => 8: Martin Van Buren (Democratic)
    [2] => 10: John Tyler (Whig)
    [3] => 5: James Monroe (Democratic-Republican)
    [4] => 4: James Madison (Democratic-Republican)
    [5] => 3: Thomas Jefferson (Democratic-Republican)
    [6] => 7: Andrew Jackson (Democratic)
    [7] => 9: William Henry Harrison (Whig)
    [8] => 2: John Adams (Federalist)
    [9] => 6: John Quincy Adams (Democratic-Republican)
)
Array
(
    [0] => 8: Martin Van Buren (Democratic)
    [1] => 7: Andrew Jackson (Democratic)
    [2] => 6: John Quincy Adams (Democratic-Republican)
    [3] => 5: James Monroe (Democratic-Republican)
    [4] => 4: James Madison (Democratic-Republican)
    [5] => 3: Thomas Jefferson (Democratic-Republican)
    [6] => 2: John Adams (Federalist)
    [7] => 1: George Washington (None)
    [8] => 10: John Tyler (Whig)
    [9] => 9: William Henry Harrison (Whig)
)

Underscore.php Mixin: sort

<?php
    __()->mixin([
        "sort" => function ($items, $ascending = true) {
            if ($ascending) {
                sort($items);
            } else {
                rsort($items);
            }
            return $items;
        }
    ]);
    
    $numbers = __()->chain()->range(10)->shuffle()->value();
    print_r($numbers);
    print_r(__($numbers)->sort());
    print_r(__($numbers)->sort(false));
    print_r($numbers);
?>

Output:

Array
(
    [0] => 5
    [1] => 1
    [2] => 3
    [3] => 0
    [4] => 6
    [5] => 8
    [6] => 4
    [7] => 9
    [8] => 7
    [9] => 2
)
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
    [6] => 6
    [7] => 7
    [8] => 8
    [9] => 9
)
Array
(
    [0] => 9
    [1] => 8
    [2] => 7
    [3] => 6
    [4] => 5
    [5] => 4
    [6] => 3
    [7] => 2
    [8] => 1
    [9] => 0
)
Array
(
    [0] => 5
    [1] => 1
    [2] => 3
    [3] => 0
    [4] => 6
    [5] => 8
    [6] => 4
    [7] => 9
    [8] => 7
    [9] => 2
)

Fixing Underscore.php

@@ -176,7 +176,7 @@ all: Wrap return value
     $__ = new self;
     if(!is_null($iterator)) $collection = $__->map($collection, $iterator);
     $collection = (array) $collection;
-    if(count($collection) === 0) return true;
+    if(count($collection) === 0) return self::_wrap(true);
     
     return self::_wrap(is_bool(array_search(false, $collection, false)));
   }
@@ -191,8 +191,8 @@ filter: Pass key to iterator
     $collection = self::_collection($collection);
     
     $return = array();
-    foreach($collection as $val) {
-      if(call_user_func($iterator, $val)) $return[] = $val;
+    foreach($collection as $k=>$v) {
+      if(call_user_func($iterator, $v, $k, $collection)) $return[] = $v;
     }
     return self::_wrap($return);
   }
@@ -205,8 +205,8 @@ reject: Pass key to iterator
     $collection = self::_collection($collection);
     
     $return = array();
-    foreach($collection as $val) {
-      if(!call_user_func($iterator, $val)) $return[] = $val;
+    foreach($collection as $k=>$v) {
+      if(!call_user_func($iterator, $v, $k, $collection)) $return[] = $v;
     }
     return self::_wrap($return);
   }
@@ -220,8 +220,8 @@ find: Pass key to iterator and wrap return value
     
     $collection = self::_collection($collection);
     
-    foreach($collection as $val) {
-      if(call_user_func($iterator, $val)) return $val;
+    foreach($collection as $k=>$v) {
+      if(call_user_func($iterator, $v, $k, $collection)) return self::_wrap($v);
     }
     return self::_wrap(false);
   }
@@ -501,7 +501,7 @@ max: Wrap return value
     arsort($results);
     $__ = new self;
     $first_key = $__->first(array_keys($results));
-    return $collection[$first_key];
+    return self::_wrap($collection[$first_key]);
   }
   
   
@@ -549,7 +549,7 @@ groupBy: Wrap return value
       if(!array_key_exists($key, $result)) $result[$key] = array();
       $result[$key][] = $v;
     }
-    return $result;
+    return self::_wrap($result);
   }
   
   
@@ -588,7 +588,9 @@ toArray: Wrap arguments and return value
   
   // Return the collection as an array
   public function toArray($collection=null) {
-    return (array) $collection;
+    list($collection) = self::_wrapArgs(func_get_args(), 1);
+    
+    return self::_wrap((array) $collection);
   }
   
   
@@ -615,7 +617,7 @@ extend: Wrap return value
     $args = self::_wrapArgs(func_get_args(), 1);
     
     $num_args = func_num_args();
-    if($num_args === 1) return $object;
+    if($num_args === 1) return self::_wrap($object);
     
     $is_object = is_object($object);
     $array = (array) $object;
@@ -635,7 +637,7 @@ defaults: Wrap return value
     list($object) = $args;
     
     $num_args = count($args);
-    if($num_args === 1) return $object;
+    if($num_args === 1) return self::_wrap($object);
     
     $is_object = is_object($object);
     $array = (array) $object;
@@ -660,7 +662,7 @@ clon: Pass argument by value
   
   
   // Returns a shallow copy of the object
-  public function clon(&$object=null) {
+  public function clon($object=null) {
     list($object) = self::_wrapArgs(func_get_args(), 1);
     
     $clone = null;
@@ -858,7 +860,7 @@ __call: Wrap return value
   public function __call($name, $arguments) {
     $mixins =& self::getInstance()->_mixins;
     $arguments = self::_wrapArgs($arguments);
-    return call_user_func_array($mixins[$name], $arguments);
+    return self::_wrap(call_user_func_array($mixins[$name], $arguments));
   }
   
   
@@ -1045,7 +1047,7 @@ compose: Apply functions in reverse order
     
     return self::_wrap(function() use ($functions) {
       $args = func_get_args();
-      foreach($functions as $function) {
+      foreach(array_reverse($functions) as $function) {
         $args[0] = call_user_func_array($function, $args);
       }
       return $args[0];