0
  $parent = array(
            array(//$parent[0]
               "a-key",
               "b-key" => array(
                            array("1", "2", "3"), //b-key[0]

                            array("4", "5", "6")) //b-key[1]                              
                ,
               "c-key"),

            array(//$parent[1]
               "a-key",
               "b-key" => array(array("7", "8", "9"), //b-key[0]
                                array("10", "16",      //b-key[1]  
                                            "12" => array(array("13"),   //12[0]
                                                          array("14"))), //12[1]

                                array("15", "16" => array(), "17"))      //b-key[2] 
               ,                                            
               "c-key"),

               array(//$parent[2]
               "a-key",
               "b-key" => array(array("7", "8", "9"), //b-key[0]
                                array("10", "16",      //b-key[1]  
                                            "12" => array(array("13"),   //12[0]
                                                          array("14"))), //12[1]

                                array("15", "16" => array(), "17"))      //b-key[2] 
               ,                                            
               "c-key")
        );

Requirement:

step1: Go to $parent last element (i.e.) $parent[2]

step2: From $parent[1] check all the key which has array value. Here b-key has array value. Go to b-key last element (i.e.) b-key[3]

step3: From b-key[3] check all the key which has array value. Here 16 has array value. Append new data here.

Expected output:"16"=>array(array("newdata"))

11
  • end() moves the pointer.. the next step is to get the key via key() you may consider first walking/traversing the array structure and returning a pointer/reference.. then work with the reference. Commented Feb 18, 2016 at 14:38
  • Then, in this case which method I can use? Commented Feb 18, 2016 at 14:39
  • I don't get it, why would you want to push data to an unknown key (or series of unknown keys...)? That will make it a lot harder to get it back / to use it. Commented Feb 18, 2016 at 14:44
  • key name is known. I want to insert data to the known keys. Am using loop to insert data . Every time it should insert to the last element of particular key. Commented Feb 18, 2016 at 14:49
  • id1 is an array. Its index should be mentioned right before calling id2 Like $section[0]['id1'][0]['id2'][0]['id3']. I want like this, but for an example I have mentioned 0 as an index. In that place of 0 I want last element index of that arrays Commented Feb 20, 2016 at 7:51

3 Answers 3

2

If I read your comment correctly, you know all the keys and want to add an element to an array that can be reached through those keys.

In that case, all you need to append it to the end of that element, is:

$section['id1']['id2']['id3'][] = $the_array_you_want_to_add;

Edit: If there is a layer more and you need to get the last element of $section first, you can use something like:

$last_key_of_section = end(array_keys($section));
$section[$last_key_of_section]['id1']['id2']['id3'][] = $the_array_you_want_to_add;
Sign up to request clarification or add additional context in comments.

8 Comments

I have updated an example in the post. Actually I need to get last element of $sectionfirst, then from that element I need to get id1 .
Thank you jeroen! it works. But If I want to get id2 from the last element of id1, how can I do it? How to do for id1 array as $section. Should it be like $section[$last_key_of_section]['id1']id1[$last_key_of_id1]['id2'] ?
if key has an array element. How to access the last element of particular key?
I think am confusing you :( Actually its not about last key, I want last element of array. That array would be the value of key . If I want to get last element of simple array I could use end($array). If key has an array. I should access the last element of array which is a value of key. So, I should use like end("keyname"), here keyname has an array as a value so it can be passed to end method?
@Learning end(array_keys($array)) is the key of the last element of the array, regardless if you use numeric or string keys. So you can use that at any level.
|
1

demonstrating my comment:

$ref = &$section;
while (is_array(end($ref))) {
    $key = key($ref);
    $ref = &$ref[$key];
}
array_push($ref, array('1','2','3'));

3 Comments

It works. But I need to insert by using key name. For example, If I want to insert an element or array to "content3" how can I specify key name to the end of array element?
what @jeroean said. if you know all the keys, this is trivial. array_merge($section['id1']['id2']['id3'], array('more','values'));
key has an array as a value. How to get last element of key(array)?
1

This is 'redo' of the code as the previous answer didn't do what anyone wanted.

Requirement:

Given:

  • 1) a root such as $section[0]
  • 2) an array of data to add ($newData)
  • 3) The key of an 'entry', with an empty array, to add the data to.

Result:

  • Replace the current empty array with the $newData.

As this is a tree, I use the term $node to refer to entries in it.

How I choose to approach it.

1) Imagine you have a class (TreeWalk) that can 'visit' every node in the tree.

2) It can run any callable (visitor) on the node.

3) The node can be modified by the visitor

So, given that the TreeWalk class exists then the means to do what is required becomes:

  • Write a visitor to identify the required node and update it.

That is what is provided here.

I will provide the 'TreeWalk' class but that is a 'general treewalk' class that is used to run the 'nodeProcessor' that will update the correct node.

Sources and Demonstration:

_Update: Added code to do what the OP asked for...

The Code (nodeProcessor):

1) The data it uses:

// new data to add to the node 
$updateData  = array( 'key' => 16, // This must be the correct type i.e string '16' will not match!
                      'data' => array('name666' => 'Kilroy_666', 
                                      'contents666' => 
                                      'Contents_666', 
                                      'id666' => array())
               );    

2) The code to be run at every node in the tree

/*
* It can be any `callable`... I use a closure but it could be a function or a method
*
* It will use:
*    o $tree                : instance passed as a parameter
*
*    o $tree->currentKey    : identify which node to update  
*    o $tree->currentNode   : a reference to the node identified by the currentKey 
* 
*    o $tree->processorData : This can be any data that you need for this routine
*                              to do what you want.
*
*          we have: array('key'  => 16,
                          'data' => array('hello', 'node 16'))  
*
*    it needs to identify the correct node and update it with the new data
*/

$updateNode = function (TreeWalk $tree) {

    if ($tree->currentKey === $tree->processorData['key']) {
        $path = $tree->showCurrentPath();
        $tree->currentNode = $tree->processorData['data'];
        $tree->endTreeWalk = true;
        return $path; 
    }
};

Run the code:

$tree = new TreeWalk($parent, $updateNode, $updateData);
$tree->treeWalk();

TreeWalk Interface:

<?php 

/*
 * The class can be found here: http://pastebin.com/wKuKrPTv
 */

Interface ITreeWalk {

    /**
    * This class processes `paths` is a tree made from arrays
    * 
    * You can provide a 'nodeProcessor' which is amy `callable` that will be 
    * run against every node.
    * 
    * Also available is the `current path` through the arrays to get to the `currentNode`.
    * 
    */


    /**
    * A reference to the current node so it can be updated 
    * 
    * @property mixed $currentNode
    */

    /**
    * The key of the currentData - readonly 
    * 
    * @propert mixed $currentKey
    */

    /**
     * The 'current' stack of nodes in this path to reach this `currentNode`
     *
     * This is a 'stack'. The 'path' is all the entries combined.
     *
     *  Each path entry is: array('key' => $currentKey, 'data' => $currentNode) 
     *
     * @property array $currentPath
     */

    /**
     * Available data to the nodeProcesor
     *
     * @property mixed $processorData
     */

    /**
     * The Output
     *
     * @property array $processorResults
     */

    /**
    * Terminate the processing of any further nodes 
    * 
    * @property boolean $endTreeWalk
    */ 


    /**
     * Build the class but do not run it...
     *
     * Provides a default NodeProcessor if you don't provide one.
     *    o The default processor builds string paths that look like  array paths
     *
     * @param array $tree
     * @param callable $processNode        - optional
     * @param processorData                - optional
     */
//    public function __construct(array &$tree,
//                                /* callable */ $processNode = null,
//                               /* mixed    */ $processorData = null);


    /**
     * This routine makes this class rather useful as you can use any callable.
     * 
     * The nodeProcessor accepts one parameter:
     *   o the instance of the 'TreeWalk'
     * 
     * It has some useful items of data available to it: 
     *   1) The `currentNode` - this is a reference so the node can be updated
     *   2) The `currentKey`  - this is the `array index' of the 'currentNode'
     * 
     *   3) The `processorData` - This is anything that you decide you need when processing
     *      the `currentNode`. 
     * 
     *   4) The full path that leads to this node.
     *      This is useful as it can be checked as part of the search conditions
     *      if you wish. 
     *
     * @param callable $nodeProcessor
     */
    public function setNodeProcessor(/* callable */ $nodeProcessor);

    /**
    * This is the data used by the `nodeProcessor` it can be anything.
    * 
    * Normally, an array?
    * 
    * @param mixed $data
    * @return void
    */
    public function setProcessorData($data);

    /**
     * Any walue returned from the 'nodeProcessor' will be stored added to this array.
     *    
     * Return a list of results were generated by the 'nodeProcessor'
     * @return array
     */
     public function results();

    /**
     * Process all the  nodes.
     * 
     * @param mixed optional - The data to be used by the `nodeProcessor`
     *
     * @return void
     */
     public function treeWalk($processorData = null);


    /**
    * show the current path as text
    * 
    * What if you don't use `foreach` - is it easier to understand? It is for me...
    * 
    * Path stucture:
    *   1) root node                                       (required) 
    *   2) an iteration of intermediate nodes              (optional) - makes sense
    *   3) end data node                                   (optional) ! 
    *        - what? yes - what if path is just the root ;-/ 
    * 
    * @return string
    */    
    public function showCurrentPath();


    /**
     * If you don't provide a callable to generate paths then this will be used.
     *
     * It generates a list string paths to all the leaf nodes.
     * 
     * @return string
     */
    // public function defaultNodeProcessor();
}

2 Comments

I want to append to the last element of GIVEN KEY NAME. From my example, I want to append to the last element of b-key .So last element of b-key is b-key[3] In that append data to 16(keyname). Should not find for empty array alone, because many keys would have empty array values. Should find for last elemnt of givenkeyname. Updated my post pls see it.
ya, first argument node should be last element. Second argument is not $lastKeyToFind, its $keyToFind

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.