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
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...

Link to comment
Share on other sites

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;
}

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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 <max.udaskin@gmail.com>
* @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>
*/

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.