X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FUtils%2FArray.php;h=575c0e66b880594f254cbab8145633d0c5ebe319;hb=1248c859b5179926424c88232e0eeee14b8ca8c2;hp=296f470a0024e07105bd12c6a882cd0b6f39f746;hpb=ecd9d5a77c1385f0fdac7465bcbcbf5e1798cfaa;p=civicrm-core.git diff --git a/CRM/Utils/Array.php b/CRM/Utils/Array.php index 296f470a00..575c0e66b8 100644 --- a/CRM/Utils/Array.php +++ b/CRM/Utils/Array.php @@ -519,7 +519,7 @@ class CRM_Utils_Array { } else { $keyvalue = $record->{$key}; } - if (!is_array($node[$keyvalue])) { + if (isset($node[$keyvalue]) && !is_array($node[$keyvalue])) { $node[$keyvalue] = array(); } $node = &$node[$keyvalue]; @@ -635,5 +635,48 @@ class CRM_Utils_Array { } return $default; } + + /** + * Generate the Cartesian product of zero or more vectors + * + * @param array $dimensions list of dimensions to multiply; each key is a dimension name; each value is a vector + * @param array $template a base set of values included in every output + * @return array each item is a distinct combination of values from $dimensions + * + * For example, the product of + * { + * fg => {red, blue}, + * bg => {white, black} + * } + * would be + * { + * {fg => red, bg => white}, + * {fg => red, bg => black}, + * {fg => blue, bg => white}, + * {fg => blue, bg => black} + * } + */ + static function product($dimensions, $template = array()) { + if (empty($dimensions)) { + return array($template); + } + + foreach ($dimensions as $key => $value) { + $firstKey = $key; + $firstValues = $value; + break; + } + unset($dimensions[$key]); + + $results = array(); + foreach ($firstValues as $firstValue) { + foreach (self::product($dimensions, $template) as $result) { + $result[$firstKey] = $firstValue; + $results[] = $result; + } + } + + return $results; + } }