/** * Defines a Structure * * This is where you specify the keys of the given fields as well * as if any fields are restricted (tagged unions). Passing * in a Restricitons object with tag (array) as an element of the array * is all that is needed to initialize a tagged union item. * * Options: strict - throw errors where applicable * insensitive - make the keys (fields) insensitive * (only for construction) Only one key of a * particular value can then exist * * @param array $allowed The field names as values, * arrays for tagged unions and restrictions * @param array $options The options for the object * */ public function __construct(array $allowed = array(), array $options = array()) { if (is_array($options)) { $options = array_change_key_case($options); } $this->configure($options); if (!$allowed) { // We haven't been given any information to // construct the structure if ($this->conf->strict) { throw new Exception\InvalidArgumentException('Structure->__construct: No Elements Given'); } return; } /* Since we are not using a map, and it wouldn't make sense * to do so since having the value (tagged union) be the key * would accomplish nothing, we generate an array with the keys * being the specified tags. These are merged in after the flip * * EX: if value is array (restrictions, tagged unions, etc ) */ $mergeArray = array(); $arrayCount = count($allowed); if ($arrayCount) { for ($i = 0; $i < $arrayCount; $i++) { if (is_array($allowed[$i]) && count($allowed[$i]) == 2) { if ($allowed[$i][0] instanceof Restrictions) { $mergeArray[$allowed[$i][1]] = new TaggedUnion($allowed[$i][0], array('strict' => $this->conf->strict)); } else { if ($allowed[$i][0] instanceof TaggedUnion) { $mergeArray[$allowed[$i][1]] = $allowed[$i][0]; } else { $mergeArray[$allowed[$i][1]] = $allowed[$i][0]; } } unset($allowed[$i]); } } } if ($this->conf->insensitive) { // make soon-to-be keys case insensitive $allowed = FalcraftResource\ArrayUtilities::array_change_value_case($allowed); } // If keys have been made insensitive, the last key value will be used $this->keysValues = array_flip($allowed); // Remove the values from keysValues (used to be keys) foreach ($this->keysValues as $k => $v) { $this->keysValues[$k] = null; } // Merge in the alternative values (these couldn't be flipped) $this->keysValues = array_merge($this->keysValues, $mergeArray); }
/** * Set Difference * * "returns the difference of sets S and T." * * This function can take multiple arrays, Sets, or values * mixed together * * @static * * @link http://en.wikipedia.org/wiki/Set_(abstract_data_type)#Core_set-theoretical_operations [English] * * @param mixed $S,... Data to difference * * @return array Difference array * */ public static function difference() { $cmp = function ($a, $b) { if ($a === $b) { return 0; } else { return -1; } }; // This closures are more compatible with set values $result = null; foreach (func_get_args() as $arg) { if ($arg instanceof TypesResource\SetInterface) { if ($result === null) { $result = $arg->getPlainArray(); } else { $result = array_udiff($result, $arg->getPlainArray(), $cmp); } } else { if (is_array($arg)) { if ($result === null) { $result = $arg; } else { $result = array_udiff($result, $arg, $cmp); } } else { if ($result === null) { $result = array($arg); } else { $result = array_udiff($result, array($arg), $cmp); } } } } // More object compatible than array_unique SORT_REGULAR return StandardResource\ArrayUtilities::returnUnique($result); }
/** * Get A Range Of Index References * * This gets an array of objects that have priorities between ranges * * NOTE: The utility function must be used because of incompatibility * of array_unique algorithm * * @param Falcraft\Data\Types\Range $r The range to include * * @return array The appropriate array * */ public function indexRangeReference(Types\Range $r) { return StandardResource\ArrayUtilities::returnUniqueByReference(array_merge($this->indexReference($r->getMinimum(), self::HIGHER), $this->indexReference($r->getMaximum(), self::LOWER))); }