How can you move an array pointer to a specific key?

I attempting to write a foo that will edit/create an array element in an ORDERED BUT NON CONTIGUOUS numeric array, calculating the new OR EDITED element’s value based on the previous arrays value.

for example
$values[thisKey]=$values[PREVIOUSKey] +5;

This would be easy, if the arrays were contiguous (ie.:1,2,3,4,5,6…) but in fact they can be (1,2,5,10,11,12,13,15…) :confused:

applying the above pattern, it should end up functioning like this:
$values[10]=$values[5] +5;

the following is the logic of my foo:


foo($keyToMakeOrEdit){
   $defaultStartValue=10;
   ksort($this->dataArray); //make sure array is in order
   if (!isset($this->dataArray[$keyToMakeOrEdit])){   // make NEW array element;
             $base=end($this->dataArray); //get the value of the last array element
     }
    else{    //we are now editing an existing key
                // need to find a way to  move the array pointer to $keyToMakeOrEdit HOW?????
               $base=prev($this->dataArray); //get the value of the last array element
     }
    reset($this->dataArray);  reset the data array , just as a precaution
    $this->dataArray[$keyToMakeOrEdit]=($base!==false) ?   $base+5 : $defaultStartValue  ;  // if the array is empty  set value to the default , else set it to the LAST ($base) key +5;
}


I just cant think of a PHP function that would let me move the array pointer to specific key (10) so that I could move it back one element and obtain that elements value. I realize , I could just ‘compress’ my array using array_values and thus have a contiguous set of keys, but unfortunately I also need to preserve the keys. Any suggestions?

Switch to an array that uses contiguous array keys.


$orig = array(
5 => array('myDataKey' => 'someData'),
7 => array('myDataKey' => 'someData'),
10 => array('myDataKey' => 'someData'),
13 => array('myDataKey' => 'someData'),
29 => array('myDataKey' => 'someData')
);

//fix you array
$counter = 0;
$new = array();
foreach($orig as $key => $val) {
array_push($new, array('oldKey' => $key, 'data' => $val));
}
unset($orig);

//run your contiguous logic, accesing the new oldKey and Data values

There is a solution i think that can help. Try using ArrayObject!.

taken from the manual


$arrayobject = new ArrayObject();

$arrayobject[] = 'zero';
$arrayobject[] = 'one';
$arrayobject[] = 'two';

$iterator = $arrayobject->getIterator();

$iterator->next();
echo $iterator->key(); //1

$iterator->rewind(); //rewinding to the begining
echo $iterator->key(); //0

I see where you are going there Wolfe… unfortunately the array serves as both interface and data storage :confused:

in other words, if a user wanted to access or insert extra data for ‘object #9’… s/he would call or create $array[9], so creating a new array parading would collapse a whole bunch of things.

jgetner, what would be the difference in mere working DIRECTLY with the existing PHP iterating foos for arrays, instead of creating an object? I was hopeful that the arrayObject class would have a prebuilt to move or iterate backwards, but alas it seems it is only the OOP version of the existing array foo

This code I wrote does what I am wanting; I was just trying to avoid creating my own foo, if PHP had a prebuilt one, also I loathe having to do this because it seems wasteful to have to iterate through an array to ‘move’ the pointer back ONE position. So if anyone can think of more efficient ways to accomplish this I am still open to suggestions.



<?php
$array = array('1' => 3,
               '2' => 5,
               '5' => 10,
               '6' => 11,
               '7' => 13,
               '10' => 15,
               '11' => 20,
               '12' => 21,
               '15' => 35,
               '18' => 50,
               '19' => 55);

function getPrevKey($key, $array){
	if (!isset($array[$key])) {return null;}
	$prevK=NULL;
	foreach ($array as $k=>$v){
		if ($k===$key){return $prevK;}
		$prevK=$k;
	}
 	return $prevK;
}


function foo($k,$array){
  echo $array[$k]+ $array[getPrevKey($k, $array)];
}


foo(5,$array); // echoes 15, $array[5]+ $array[2]
?>

You could use some array functions to find the previous key (if there is one), if I’m understanding the above code correctly. Something like the following,


function foo($k,$array){
    $keys = array_keys($array);
    $key  = array_search($k, $keys);
    if ($key > 0) {
        // Key found, and there is a previous key
        return $array[$k] + $array[$keys[$key-1]];
    } elseif ($key === 0) {
        // Key found, no previous key
        return $array[$k];
    } else {
        // Key not found
        // Throw an exception, trigger an error?
    }
}

Ohh, create an index as you go…


$MyArray = array('1' => 3,
               '2' => 5,
               '5' => 10,
               '6' => 11,
               '7' => 13,
               '10' => 15,
               '11' => 20,
               '12' => 21,
               '15' => 35,
               '18' => 50,
               '19' => 55);
$MyArrayIndex() = array();
$counter = 0;
foreach($MyArray as $key => $val) {
  if(array_search($key, $MyArrayIndex()) === false) { // make sure you use 3 to do identical match, not type juggling due to 0's
    array_push($MyArrayIndex, $key);
  } else {
   Throw New Exception();
}
  if($foo) {
    //my -5 value
    $minus5Val = $MyArray[$MyArrayIndex[$counter-5]];
  }
  $counter++;
}

This will now create a new array, much like what I was trying to do, but will be seperate. As you walk down the array and you need to reference

Salathe,
the COMBINED implementation of to array_keys() and array_search() is exactly the solution. Brilliant, thank you so much. I was trying to find I am kinda kicking myself for not having glimpsed it earlier.

for the curious this is a sample of how I put it to work:


<?php
$array = array('1' => 3,
               '2' => 5,
               '5' => 10,
               '6' => 11,
               '7' => 13,
               '10' => 15,
               '11' => 20,
               '12' => 21,
               '15' => 35,
               '18' => 50,
               '19' => 55);

function getPrevKey($k, $array){
    $keys = array_keys($array);
    $key  = array_search($k, $keys); 
    if ($key>0){return $array[$keys[$key-1]];} 	// if there is a previous key return its value
    return 0; 									//else return nothing ( leaving the final answer unaffected 
 }
function foo($k,$array){						// output fucntion for the sake of testing
  if (!isset($array[$k])){return;}				// error prevention in case the point of reference key doesnt exist
  echo $array[$k] +   getPrevKey($k, $array);
}


foo(5,$array); // echoes 15, $array[5]+ $array[2]
foo(4,$array); // echoes nothing
foo(1,$array); // echoes 3, $array[1] +0
 ?>