rfc:array_part

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
rfc:array_part [2012/05/14 10:27] – [Sample implementation] cataphractrfc:array_part [2012/05/14 11:05] – [Specification for the function] cataphract
Line 23: Line 23:
 The parameter ''$partSpecification'' is a sequentially indexed numeric array that specifies the slice to extract at each "level" of the original array. A level //n// (with //n// >= 0) of an array ''$arr'' is the set of array elements than can be fetched by "dereferencing" the array //n// times. For instance, the array ''%%[[1],[['a','b']]]%%'' has at level 0 itself, at level 1 the elements ''%%[1]%%'' and ''%%[['a','b']]%%'' and at level 2 the elements ''1'' and ''%%['a','b']%%''. ''%%$partSpecification[0]%%'' shall give the part specification for level 1, and, in, general, ''%%$partSpecification[m]%%'' for level //m + 1//. The parameter ''$partSpecification'' is a sequentially indexed numeric array that specifies the slice to extract at each "level" of the original array. A level //n// (with //n// >= 0) of an array ''$arr'' is the set of array elements than can be fetched by "dereferencing" the array //n// times. For instance, the array ''%%[[1],[['a','b']]]%%'' has at level 0 itself, at level 1 the elements ''%%[1]%%'' and ''%%[['a','b']]%%'' and at level 2 the elements ''1'' and ''%%['a','b']%%''. ''%%$partSpecification[0]%%'' shall give the part specification for level 1, and, in, general, ''%%$partSpecification[m]%%'' for level //m + 1//.
  
-Each part specification shall be of one the following forms:+Each part specification shall have one of the following forms:
  
-  * An sequentially indexed numeric array of indexes, which specifies that only the elements existing at those indexes will be kept.+  * A sequential numeric array of indexes, which specifies that only the elements existing at those indexes will be kept.
   * A single index, which specifies that only the element existing at that index will be kept. In this case the level will be collapsed onto the previous one, meaning all the arrays at that level will be replaced with its element the specified index.   * A single index, which specifies that only the element existing at that index will be kept. In this case the level will be collapsed onto the previous one, meaning all the arrays at that level will be replaced with its element the specified index.
-  * A span part specification is an associative array. The following keys are allowed //start//, //end// and //step//. At least //start// or //end// must be specified. //start// and //end// are an index or a special value -- ''null''. //step// is a non-zero integer. If ''start'' or ''end'' are not specified, they default to ''null'', which refer to either the first or last element depending on the sign of //step//. If //step// is +-1 and //start// and //end// are both ''null'' (or, if ''$indexesAreKeys'' is ''false'', //start// and //end// are //0// and //-1// or vice-versa depending on the sign of //step//), then we say the span encompasses are all elements on that level (possibly 0).+  * A span part specification is an associative array. The following keys are allowed //start//, //end// and //step//. At least //start// or //end// must be specified. //start// and //end// are an index or a special value -- ''null''. //step// is a non-zero integer, defaulting to ''1''. If ''start'' or ''end'' are not specified, they default to ''null'', which refer to either the first or last element depending on the sign of //step//. If //step// is +-1 and //start// and //end// are both ''null'' (or, if ''$indexesAreKeys'' is ''false'', //start// and //end// are //0// and //-1// or vice-versa depending on the sign of //step//), then we say the span encompasses all elements on that level (possibly 0).
  
 Span parts extract any number of elements (possibly 0) starting at the index specified by //start// and advancing until //end// is reached, advancing in steps of //step//. The element at the index specified at //end// is included. Span parts extract any number of elements (possibly 0) starting at the index specified by //start// and advancing until //end// is reached, advancing in steps of //step//. The element at the index specified at //end// is included.
Line 34: Line 34:
 An index //i// has the following meaning: An index //i// has the following meaning:
   * If ''$indexesAreKeys'' is ''false'' and //i// is a non-negative integer (possibly after casting) then an element is at index //i// if it //i// is the the number of times one would have to call ''next()'' after calling ''reset()'' for ''current()'' to return that element.   * If ''$indexesAreKeys'' is ''false'' and //i// is a non-negative integer (possibly after casting) then an element is at index //i// if it //i// is the the number of times one would have to call ''next()'' after calling ''reset()'' for ''current()'' to return that element.
-  * If ''$indexesAreKeys'' is ''false'' and //i// is a negative number, then an element is at positive //i// if //-i+1// is the number of times one would have to call ''prev()'' after calling ''end()'' for ''current()'' to return that element.+  * If ''$indexesAreKeys'' is ''false'' and //i// is a negative integer, then an element is at index //i// if //-i-1// is the number of times one would have to call ''prev()'' after calling ''end()'' for ''current()'' to return that element.
   * If ''$indexesAreKeys'' is ''true'' then an element is at //i// if its array key is //i//.   * If ''$indexesAreKeys'' is ''true'' then an element is at //i// if its array key is //i//.
 +
 +The keys in the original array are not preserved in the output, expect at levels that were not visited.
  
 This function shall return ''false'' upon finding error conditions. The following are error conditions: This function shall return ''false'' upon finding error conditions. The following are error conditions:
Line 41: Line 43:
   * Giving arguments with different PHP types from those specified.   * Giving arguments with different PHP types from those specified.
   * Giving malformed part specifications (where the individual elements do not follow the syntactic rules given here).   * Giving malformed part specifications (where the individual elements do not follow the syntactic rules given here).
-  * Specifying an part index than does not exist at at least of the elements at the level the part refers to: (e.g. ''%%array_part([[1],[1,2]],   [['start'=>0, 'end'=>-1], 1])%%'' is an error condition, because while ''1'' is a valid index for ''%%[1,2]%%'', it is not so for ''1''). However, span part specifications that comprise all elements are always accepted. +  * Specifying an part index than does not exist at at least of the elements at the level the part refers to: (e.g. ''%%array_part([[1],[1,2]],   [['start'=>0, 'end'=>-1], 1])%%'' is an error condition, because while ''1'' is a valid index for ''%%[1,2]%%'', it is not so for ''%%[[1]]%%''). However, span part specifications that comprise all elements are always accepted. 
-  * Giving a part specification with levels that do not exist in the input. This does not apply if, as a result of a span part that comprises all the elements of that level and at the level before existing only empty arrays, no elements were left for the next element. For instance '%%array_part({}, [['start'=>0, 'end'=>-1]])%%' is valid, as is '%%array_part([[]], [0, ['start'=>0, 'end'=>-1], 1, 2, 3])%%', which will return ''%%[[]]%%''.+  * Giving a part specification with levels that do not exist in the input. This does not apply if, as a result of a span part that comprises all the elements of that level and at the level before existed only empty arrays, no elements were left for the next level. For instance '%%array_part([], [['start'=>0, 'end'=>-1]])%%' is valid, as is '%%array_part([[]], [0, ['start'=>0, 'end'=>-1], 1, 2, 3])%%', which will return ''%%[[]]%%''.
   * Encountering already visited array elements from the original array (recursion).   * Encountering already visited array elements from the original array (recursion).
  
Line 49: Line 51:
 A sample implementation, with tests exemplifying the use of this function, [[https://gist.github.com/2660601|is available]]. A sample implementation, with tests exemplifying the use of this function, [[https://gist.github.com/2660601|is available]].
  
-[https://gist.github.com/2660601#file_test.php|Direct link to the tests]+[[https://gist.github.com/2660601#file_test.php|Direct link to the tests]]
  
 ===== Objections ===== ===== Objections =====
Line 65: Line 67:
 **The $indexesAreKeys = false mode is inefficient because there's no constant time access to the n-th element** **The $indexesAreKeys = false mode is inefficient because there's no constant time access to the n-th element**
  
-This is true. We must traverse the array from the start or the end to get to the n-th element. That's just the way PHP arrays are implemented. However, if you have numeric sequential arrays, you can use ''$indexesAreKeys = true'' to access the n-th element without this penalty.+This is true. We must traverse the array from the start or the end to get to the n-th element. That's just the way PHP arrays are implemented. However, if you have numeric sequential arrays, you can use ''$indexesAreKeys = true'' to access the n-th element without this penalty (also note that the sample implementation is **not** optimized).
  
 ===== Changelog ===== ===== Changelog =====
rfc/array_part.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1