Last active
October 2, 2015 01:57
-
-
Save hjc/2148747 to your computer and use it in GitHub Desktop.
PHP: Add a key to an associative array and keep it's key ordering intact and sequential
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implements add_to_assoc_numeric | |
* | |
* Goal of this function is to allow us to modify an associative, numeric array | |
* (one that uses string numbers as keys, so there is no 0,1,2,3 ordering, but | |
* rather the ordering is based on when the keys were inserted [they are treated | |
* like other string keys]). If we modify this array using array_unshift or | |
* array_shift, we destory this associative, numeric structure (each key is | |
* destroyed and the array is simply renumbered, with ints, from 0 to num_elems), | |
* which we don't want. This function will allow us to insert a new value anywhere | |
* in the string and order it correctly, as long as we want consecutive ordering | |
* (why wouldn't we?). | |
* | |
* Example, our array ($animals) is: | |
* '4' => 'Dog', | |
* '5' => 'Cat', | |
* '8' => 'Racoon', | |
* | |
* And we want to add in 'Mouse' to position '3' (because its our third favorite | |
* animal, for example). Using: $animals['3'] will make the array structure: | |
* '4' => 'Dog', | |
* '5' => 'Cat', | |
* '8' => 'Racoon', | |
* '3' => 'Mouse', | |
* | |
* Which we don't want because it misorders select lists, using this function would | |
* give us: | |
* '3' => 'Mouse', | |
* '4' => 'Dog', | |
* '5' => 'Cat', | |
* '8' => 'Racoon', | |
* Keeping the order of our lists correct! | |
* | |
* String is expected to be fully numeric (odd behavior can occur elsewise). | |
* | |
* Has bonus benefit of sorting an unsorted associative array that uses numeric | |
* string keys. Since sorting in associative arrays is based on when the elements | |
* were inserted, they can get out of order quickly. This function naturally | |
* sorts them | |
* | |
* @param &$assoc | |
* Array keyed with sequential, numeric string keys. We want to add a new value | |
* into this array in a specified position, but we want to keep this array's | |
* current structure. Will not be returned, but rather altered by reference | |
* | |
* @param $new_pos | |
* The position where we want the new element to go in. This position will then | |
* be placed in the correct order in the array. Example, we have these keys: | |
* 0, 1, 4, 5 and want to add key 3 which is passed in as $new_pos. This function | |
* lets us make an array with this key ordering: 0, 1, 3, 4, 5 and not: 0, 1, 4, 5, 3 | |
* | |
* @param $new_val | |
* The new value we want to put in the position/key specified by $new_pos | |
* | |
* @return &$assoc | |
* No real return, the contents of the passed in array are changed by reference | |
* due to the array's passing method. | |
*/ | |
function add_to_assoc_numeric(&$assoc, $new_pos, $new_val = NULL) { | |
// Declare new array to hold new element + old in correct order | |
$new_assoc = array(); | |
// Get a list of the arrays keys | |
$keys = array_keys($assoc); | |
//sort keys for faster iteration | |
sort($keys); | |
//store size of keys array | |
$keys_size = count($keys); | |
// Get max key for bounds | |
$min = $keys[0]; | |
//Get min key for bounds | |
$max = $keys[$keys_size - 1]; | |
//set iterator | |
$place = 0; | |
//See if new position is greater than our current minimum, if so we have | |
//to populate the intermediary values, otherwise there are none | |
if ($new_pos > $min) | |
{ | |
//Populate values between $min and $new_pos | |
for (; $keys[$place] < $new_pos; $place++) { | |
//Cast to string to get right key | |
$new_assoc[(string)$keys[$place]] = $assoc[(string)$keys[$place]]; | |
} | |
} | |
//Add new value in its position, perfectly placing it in order | |
$new_assoc[(string)$new_pos] = $new_val; | |
//Add remaining elements of array, if new position is greater than greatest | |
//current key, for loop is skipped | |
for (; $place < $keys_size; $place++) { | |
$new_assoc[(string)$keys[$place]] = $assoc[(string) $keys[$place]]; | |
} | |
//Set $assoc to $new_assoc to change array | |
$assoc = $new_assoc; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment