Skip to content

Instantly share code, notes, and snippets.

@DeMarko
Created March 1, 2013 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeMarko/5066740 to your computer and use it in GitHub Desktop.
Save DeMarko/5066740 to your computer and use it in GitHub Desktop.
mergeByFunction, mergeByProperty
<?php
/**
* Merge two arrays by extracting a key for each element with a function $f
* @param $f function which returns a scalar given any of the members of $array1 or $array2
* @param $array1
* @param ...
*
* @return array keyed by the output of $f on elements of the arrays passed in
*/
public static function mergeByFunction ($f, $array1) {
$merged = array();
$arguments = func_get_args();
if (count($arguments) < 2) {
throw new InvalidArgumentException(__METHOD__." cannot apply function to empty arguments");
}
$f = array_shift($arguments);
if (!is_callable($f)) {
throw new InvalidArgumentException(__METHOD__." needs a valid function!");
}
foreach ($arguments as $array_argument) {
if (!is_array($array_argument)) {
$array_argument = array($array_argument);
}
foreach ($array_argument as $array_member) {
if ($array_member) {
$merged[$f($array_member)] = $array_member;
}
}
}
return $merged;
}
/**
* A convenience function for mergeByFunction that covers a very general
* case where you want to merge two or more arrays of objects by a common
* property of those objects. Later objects with the same property value
* will replace earlier ones.
*
* @param $property string of the common property of the objects
* @param $array1 array of objects of the same type
* @param ... more arrays of objects of the same type
*
* @return array of all the objects keyed by the value of the individual properties
*/
public static function mergeByProperty ($property, $array1) {
$merged = array();
$arguments = func_get_args();
if (count($arguments) < 2) {
throw new InvalidArgumentException(__METHOD__." cannot extract property from empty arguments");
}
$property = array_shift($arguments);
$extract_function = create_function('$object', 'return $object->'.$property.';');
// for the curious, this can also be expressed as:
/*
$extract_function = function ($object) use ($property) {
return $object->$property;
};
*/
array_unshift($arguments, $extract_function);
$merged = call_user_func_array(array(__CLASS__, "mergeByFunction"), $arguments);
return $merged;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment