Return to Snippet

Revision: 37701
at December 15, 2010 12:41 by RobertWHurst


Initial Code
/**
 * Takes an two arrays and merges them. the first array is used as
 * a template or mask, and the second array is applied over top.
 * If the second array contains variables or structure not present
 * in the first array it is discarded.
 *
 * The first array acts as a mask on the second array.
 * 
 * @author Robert Hurst
 * @website http://thinktankdesign.ca/
 *
 * @param  $defaults
 * @param  $arguments
 * @param bool $keep_unset
 * @return array
 */
private function mask_array($defaults, $arguments, $keep_unset = false) {

	/*
	 * If the arguments are invalid or broken fail gracefully by
	 * returning first argument.
	 *
	 * Note: this is done instead of returning false to prevent serious
	 * failures in other methods or functions that depend on this method.
	 * This is extremely important in recursive or self executing functions.
	 */
	if( ! is_array( $defaults ) || ! is_array( $arguments ) ){
		return $defaults; //just return the defaults (something goofed)
	}

	/*
	 * Copy the default array (the mask) to the results array. If the second
	 * array is invalid or does not match the mask at all, the default mask
	 * will be returned.
	 */
	$results = $defaults;

	//loop through the second array
	foreach( $arguments as $key => $argument ){

		/*
		 * Check to see if the method is set to discard unmasked data, or if
		 * the current argument does not fit within the default mask array.
		 * If both of these are false then discard the variable or structure
		 */
		if( ! $keep_unset && ! isset( $defaults[$key] ) )
			continue; //the option is invalid

		/*
		 * If the current argument is more array structure instead of a
		 * variable then check if it fits in the default mask. if it does
		 * re execute on it.
		 */
		if( is_array( $argument ) ){

			/*
			 * If the mask has a variable instead of structure in this position.
			 */
			if( !is_array( $defaults[$key] ) ){

				/*
				 * Check to see if the method is set to discard unmasked structure.
				 * If the method is set to keep unmasked structure then replace the
				 * mask's variable with this structure.
				 */
				if( $keep_unset ){
					$results[$key] = $argument;
				}

				//continue to the next item in the second array.
				continue;
			}

			/*
			 * re execute on the current structure and the current mask position.
			 */
			$results[$key] = mask_array($defaults[$key], $argument, $keep_unset);

		/*
		 * If the current argument is a variable then save it to the results. Make
		 * sure the mask does not specify structure.
		 */
		} else {

			/*
			 * If the mask contains structure at this position then skip to the next
			 * variable.
			 */
			if( is_array( $defaults[$key] ) ){
				continue;
			}


			// save the current variable to the results array.
			$results[$key] = $argument;
		}
	}

	/*
	 * After processing all of the array structure, return the new filtered
	 * array.
	 */
	return $results;

}

Initial URL
http://thinktankdesign.ca/

Initial Description
Summary
=======
A useful function for masking arrays. Very useful if you have a function or method that takes arguments in an array, and you would like to force that array to have a specific structure.

Its also great for setting defaults due to the fact that whatever structure or variables that are missing from the arguments array, and are present in the default (mask) array will be copied from the default array and merged into the returned array.

Description
========

**mask_array**( array $defaults , array $arguments [, bool $keep_unset ] )

Accepts two arrays. The first array is used as a mask on the second array.


Parameters
========

**$defaults** - An array of defaults to use as a mask.
**$arguments** - An array of arguments to be filtered by the mask array.
**$keep_unset** - Setting this to true disables discarding variables and structure that will not fit within the mask.

Example
======

    /* 
      * Basic use case
      */
     
    $defaults = array(
        'colour' => 'red',
        'shape' => 'circle'
        'size' => 'large'
    );

    $arguments = array(
        'colour' => 'blue'
        'wooden' => true
    );

    $filtered = mask_array($defaults, $arguments) ;

Result
====

**$filtered** will look like this:

    array(
        color => blue,
        shape => circle,
        size => large
    )

Note that the key 'broken' is discarded, while the color is carried over.

If the third argument is set to true the result would be the following:

    array(
        color => blue,
        shape => circle,
        size => large,
        wooden => true
    )

Note that because keep unset is true the mask does not cut out the key 'broken' is included.

Hope that you find this useful

~Robert Hurst

Initial Title
Mask Array Function - for setting default array structures and masking

Initial Tags
php, array

Initial Language
PHP