SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,798
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)

    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...) :/

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

    the following is the logic of my foo:
    Code:
    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?

  2. #2
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,182
    Mentioned
    65 Post(s)
    Tagged
    2 Thread(s)
    Switch to an array that uses contiguous array keys.

    Code PHP:
    $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

  3. #3
    SitePoint Zealot
    Join Date
    Jan 2011
    Location
    Portland
    Posts
    148
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There is a solution i think that can help. Try using ArrayObject!.

    taken from the manual
    PHP Code:
    $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 
    coming soon sitejuju.com my new development portfolio

  4. #4
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,798
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    I see where you are going there Wolfe.. unfortunately the array serves as both interface and data storage :/

    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.





    Code:
    <?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]
    ?>

  5. #5
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,397
    Mentioned
    63 Post(s)
    Tagged
    0 Thread(s)
    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,

    PHP Code:
    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?
        
    }

    Salathe
    Software Developer and PHP Manual Author.

  6. #6
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,182
    Mentioned
    65 Post(s)
    Tagged
    2 Thread(s)
    Ohh, create an index as you go...

    Code PHP:
    $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

  7. #7
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,798
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    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 Code:
    <?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
     
    ?>


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •