Jump to content

Access Array Key from Array of Keys


maxudaskin

Recommended Posts

The title makes it sound more complicated than it is.

 

I have a recurring function that searches for a specific value in a multi-dimensional array. When it finds it, it returns an array of the index.

 

For example, if it found the value at $array[1][4][2][0], it would return an array like this:

[0]=>1

[1]=>4

[2]=>2

[3]=>0

 

Here's the function.

<?php

// Other Code

/**
* Find's the parent of an item
* Unfortunately, it takes a bit more work than just using the loudspeaker at a grocery store
* @param int $parent The parent to be searched for
* @param array $array 
* @param array $cur_index
*/
private function findParent($parent, $array, $cur_index)
{
    for($i = 0; $i < count($array); $i++) { // Search the array
        if($array[$i]['id'] == $parent) { // If the parent is found
            $cur_index[count($cur_index)] = $i;
            return array(true, $cur_index);
        }

        if(count($array[$i][1]) > 1) { // Call findParent again to search the child
            $cur_index[count($cur_index)] = $i;
            $found_in_child = $this->findParent($parent, $array[$i], $cur_index);
            if($found_in_child[0]) {
                return $found_in_child;
            }
        }
    }
    
    return array(false); // Return no matches
}

 

I need to be able to call that index using the keys from the key array (as we will call it). How can I do that?

 

Thank you in advance for your help.

Link to comment
https://forums.phpfreaks.com/topic/233639-access-array-key-from-array-of-keys/
Share on other sites

Found this, which might help:

http://www.php.net/manual/en/language.variables.variable.php#87564

On the topic of variable variables with arrays, I have a simple function that solves the issue. It works for both indexed and associative arrays, and allows use with superglobals.

 

<?php

function VariableArray($arr, $string)

    {

    preg_match_all('/\[([^\]]*)\]/', $string, $arr_matches, PREG_PATTERN_ORDER);

   

    $return = $arr;

    foreach($arr_matches[1] as $dimension)

        {

        $return = $return[$dimension];

        }

       

    return $return;

    }

 

$test = array('one' => 'two', 'four' => array(8));

 

$foo = 'test';

$bar = $$foo;

$baz = "[one]";

$var = VariableArray($bar, $baz); //$var now contains 'two'

 

$baz = "[four][0]";

$var = VariableArray($bar, $baz); //$var now contains int(8)

?>

 

You can simply pass in a superglobal as the first argument. Note for associative arrays don't put quotes inside the square braces unless you adjust the regexp to accept it. I wanted to keep it simple.

 

You can use a foreach to build the index part ([1][4][2][0])

foreach($return as $key) $index .= "[$key]";

 

Maybe someone else will know an easier way...

Just wrote this now. Untested.

function search(array $array, $for) {
foreach ($array as $key => $value) {
	if ($value === $for) {
		return array($key);
	} else if (is_array($value)) {
		$found = search($value, $for);
		if (is_array($found)) {
			array_unshift($found, $key);
			return $found;
		}
	}
}
return false;
}

It sounds complicated if I describe it in words. How about this?

$array = array(1, array(2, 3), array(4, array(5)))

search($array, 5) loop:
* $key=0 $value=1 - no match, not an array
* $key=1 $value=[...] - no match, is an array
  search($array[1], 5) loop:
  * $key=0 $value=2 - no match, not an array
  * $key=1 $value=3 - no match, not an array
  > return false
* $key=2 $value=[...] - no match, is an array
  search($array[2], 5) loop:
  * $key=0 $value=4 - no match, not an array
  * $key=1 $value=[...] - no match, is an array
    search($array[2][1], 5) loop:
    * $key=0 $value=5 - match
    > return array(0)
  > return array(1) + array(0)
> return array(2) + array(1, 0)

Pretty much, I need to get the parent item, stick the array of information from the item into the parent's array (key [1]) and in the end, go through a loop to transform it into a multi-drop down menu.

 

Here's the code I have right now, still rough due to it still being in the production stages. I have an example of the final html output at the bottom.

<?php
/**
* Menu Class
*
* This file is used to create a dynamic menu based on the user's permissions and status
* @author Max Udaskin <[email protected]>
* @version 1.0
* @package navigation
*/

/**
* @ignore
*/
if(!defined('ALLOW_ACCESS')) { // Do not allow the file to be accessed by itself
    die('Restricted File.');
}

require_once("Database.php");

class Menu
{
    protected $login;
    protected $all_rows;
    protected $menu_items;
    protected $html = NULL;
    protected $menu = array();

    /**
     * The constructor
     * @param Login $login
     */
    function _construct()
    {
    }

    /**
     * Get All Items
     * Retrieves all database menu items
     */
    private function getAllItems()
    {
        $sql = 'SELECT * FROM `menu` ORDER BY `parent` ASC, `sort` ASC';
        $database = new Database('default');
        $database->connect();
        $database->fetchArray($sql);
        $query = $database->getLastQuery();

        $i = 0;
        while($row = mysql_fetch_array($query))
        {
            $this->all_rows[$i] = $row;
            $i++;
        }
    }

    /*
     * Selects the menu items that are appropriate for the user
     */
    private function chooseMenuItems()
    {
        $this->menu_items = $this->all_rows;
    }

    /**
     * Formats the menu items for the HTML output
     */
    private function formatMenuItems()
    {
        $menu = array();
        $menu_imploded = '';

        for($i = 0; $i < count($this->menu_items); $i++) {
            $cur_item = $this->parseItem($this->menu_items[$i]);
            if($cur_item['parent'] == 0) {
                unset($cur_item['parent']);
                $this->menu[count($this->menu)] = $cur_item;
            } else {
                $parent = $this->search($this->menu_items, $cur_item['parent']);
                print_r($parent);
            }
        }

        for($i = 0; $i < count($menu); $i++) {
            $menu_imploded .= implode('', $menu[$i]);
        }
        //print_r($this->menu);
        echo '<div id="menu">';
        echo $menu_imploded;
        echo '</div>';
    }
    
    /**
     * Searches an array and it's sub arrays for a defined value ($for)
     * @param array $array
     * @param mixed $for
     */
    private function search(array $array, $for) {
        foreach ($array as $key => $value) {
            if ($value === $for) {
                return array($key);
            } else if (is_array($value)) {
                $found = $this->search($value, $for);
                if (is_array($found)) {
                    array_unshift($found, $key);
                    return $found;
                }
            }
        }
        return false;
    }

    /**
     * Parses HTML for the item, as an array
     * @param array $item
     */
    private function parseItem($item)
    {
        if($item['parent'] == 0) {
            $h2_s = '<h2>';
            $h2_e = '</h2>';
        } else {
            $h2_s = '';
            $h2_e = '';
        }
        $return[0] = '<ul><li>' . $h2_s . '<a href="';
        $return[0] .= $item['link'] . '">';
        $return[0] .= $item['label'] . '</a>' . $h2_e;
        $return[1] = array(); // Children
        $return[2] = '</li></ul>';
        $return['parent'] = $item['parent'];

        return $return;
    }

    /**
     * Puts all of the HTML in the array together
     */
    private function produceHtml()
    {
        $this->getAllItems();
        $this->chooseMenuItems();
        $this->formatMenuItems();
    }

    /**
     * Get HTML
     * @return string The HTML menu
     */
    public function getHtml()
    {
        $this->produceHtml();
        return $this->html;
    }
}

/*
* <div id="menu">
<ul>
<li><h2>CSS Drop Down Menus</h2>
<ul>
<li><a href="http://www.seoconsultants.com/tips/css/#cssmenus"
title="SEO Consultants Directory">CSS Hover Navigation</a>
<ul>
<li><a href="../css-dropdown-menus.html"
title="tanfa Introduction">Intro for CSS Enthusiasts</a></li>
<li><a href="index.html" title="Plain HTML Code">Demonstration
HTML</a></li>
<li><a href="http://www.xs4all.nl/~peterned/csshover.html"
title="whatever:hover file">csshover.htc file</a></li>
</ul>
</li>
</ul>
</li>
</ul>

<ul>
<li><h2>Vertical CSS Pop-Out Menu</h2>
<ul>
<li><a href="http://www.seoconsultants.com/css/menus/vertical/"
title="SEO Consultants Vertical Example">SEO Consultants Sample</a>
</li>
<li><a href="vs7.html" title="Complete Example">tanfa Demo example</a>
<ul>
<li><a href="index.html#">tanfa Tutorial</a> <!-- link to seo vertical tut -->
<ul>
<li><a href="vs1.html" title="Vertical Menu - Page 1">Stage 1</a>
</li>
<li><a href="vs2.html" title="Vertical Menu - Page 2">Stage 2</a>
</li>
<li><a href="vs3.html" title="Vertical Menu - Page 3">Stage 3</a>
</li>
<li><a href="vs4.html" title="Vertical Menu - Page 4">Stage 4</a>
</li>
<li><a href="vs5.html" title="Vertical Menu - Page 5">Stage 5</a>
</li>
<li><a href="vs6.html" title="Vertical Menu - Page 6">Stage 6</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

<ul>
<li><h2>Horizontal Drop & Pop Menu</h2>
<ul>
<li><a href="http://www.seoconsultants.com/css/menus/horizontal/"
title="SEO Consultants Directory Example">SEO Consultants Sample</a>
</li>
<li><a href="hs7.html">tanfa Demo example</a> <!-- fully working sample -->
<ul>
<li><a href="index.html#">tanfa Tutorial</a> <!-- link to horizontal tut -->
<ul>
<li><a href="hs1.html" title="Horizontal Menu - Page 1">Stage
1</a></li>
<li><a href="hs2.html" title="Horizontal Menu - Page 2">Stage
2</a></li>
<li><a href="hs3.html" title="Horizontal Menu - Page 3">Stage
3</a></li>
<li><a href="hs4.html" title="Horizontal Menu - Page 4">Stage
4</a></li>
<li><a href="hs5.html" title="Horizontal Menu - Page 5">Stage
5</a></li>
<li><a href="hs6.html" title="Horizontal Menu - Page 6">Stage
6</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
*/

 

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.