0

I need to figure out a way to partial match a string to a sub key in my PHP array.

example:

string = howdy-doody show as you can see there is a - dash and a space between the words. In my PHP array the sub key might be howdy doody show with no dashes or it might be howdy doody-show with the dash between a different word in the string.

How can I find the sub key in the array with the string given?

sample array

$pages = array(

'Administrator' => array(
    'network-administrator' => array('title' => 'Network '.$li_1, 'description' => 'Network '.$li_1.' '.$temp_content, 'post' => '<p>Network '.$li_1.' '.$temp_content.'.</p>'),
    'database administrator' => array('title' => 'Database '.$li_1, 'description' => 'Database '.$li_1.' '.$temp_content, 'post' => '<p>Database '.$li_1.' '.$temp_content.'.</p>'),
),

'Analyst' => array(
    'business systems analyst' => array('title' => 'Business Systems '.$li_2, 'description' => 'Business Systems '.$li_2.' '.$temp_content, 'post' => '<p>Business Systems '.$li_2.' '.$temp_content.'.</p>'),
    'data-analyst' => array('title' => 'Data '.$li_2, 'description' => 'Data '.$li_2.' '.$temp_content, 'post' => '<p>Data '.$li_2.' '.$temp_content.'.</p>'),
),

);

sample string

network administrator

sample variable to locate the array value

$content = $pages['Administrator']['network administrator'];

with the above variable it won't find the sub key in the array because the sub key uses a - dash like this network-administrator.

So how would I get the array value including the original subkey and returns its contents using the string that has the space instead of dash like so, network administrator?

Much appreciated for help!

Mike
  • 607
  • 8
  • 30
  • Replace all possible special characters with spaces in the strings you compare and the string you accept for comparison, but still print the returned values without anything replaced. – Ohgodwhy Sep 27 '14 at 18:41
  • yes that is what I want to do. I already have the strings stripped of their special characters with all spaces between words. So how do I write the above variable to find the sub key in the array which does have special characters in it? – Mike Sep 27 '14 at 18:44
  • either use a regex with `.` in place of the spaces/funny characters, or strip the funny characters from the array keys. – i alarmed alien Sep 27 '14 at 18:47
  • I need to return the sub keys in the array exactly the way they are with the special characters, so removing them is not an option. – Mike Sep 27 '14 at 18:48
  • you can create a second array with stripped keys as the keys and the original keys as the values. – i alarmed alien Sep 27 '14 at 18:49
  • I need to return the original sub keys with special characters and all array and sub array contents. I think I see your point, I'm trying to figure out how to do that. I'm learning PHP. – Mike Sep 27 '14 at 18:54
  • What you probably need is an array walker function. – Ohgodwhy Sep 27 '14 at 18:58
  • I edited my answer, it works perfectly, hope it helped. – Adam Sinclair Sep 27 '14 at 19:52

2 Answers2

1

Here is a function that use recursion and get you the array you passed to it but with new keys:

function getArr($arr, $reg, $char)
{
    foreach ($arr as $key => $value) {
        if (is_array($value))
            $newArray[preg_replace($reg, $char, $key)] = getArr($value, $reg, $char);
        else
            $newArray[preg_replace($reg, $char, $key)] = $value;
    }
    return $newArray;
}

Example:

You first need to get your new Array, in this case we would like to change in keys: '_' and '-' to space:

$newPages = getArr($pages, '/_|-/', ' ');

and then use our new array:

$content = $newPages['Administrator']['network administrator'];

Example in your case:

<?php
function getArr($arr, $reg, $char)
{
    foreach ($arr as $key => $value) {
        if (is_array($value))
            $newArray[preg_replace($reg, $char, $key)] = getArr($value, $reg, $char);
        else
            $newArray[preg_replace($reg, $char, $key)] = $value;
    }
    return $newArray;
}
$pages = array(

'Administrator' => array(
    'network-administrator' => array('title' => 'Network ', 'description' => 'Network', 'post' => '<p>Network</p>'),
    'database administrator' => array('title' => 'Database ', 'description' => 'Database', 'post' => '<p>Database</p>'),
),

'Analyst' => array(
    'business systems analyst' => array('title' => 'Business Systems ', 'description' => 'Business Systems', 'post' => '<p>Business Systems</p>'),
    'data-analyst' => array('title' => 'Data', 'description' => 'Data', 'post' => '<p>Data </p>'),
),

);

$content = getArr($pages, '/_|-/', ' ')['Administrator']['network administrator']['title'];
echo $content;

OUTPUT

Network 
Adam Sinclair
  • 1,654
  • 12
  • 15
  • how do I write my variable `$content = $pages['Administrator']['network administrator'];` which uses your function? – Mike Sep 27 '14 at 19:03
1

Here's one way to do it: remap your original keys to a new array containing stripped keys, and store the original key in the value for the array.

$t_keys = array();

foreach ($pages as $k => $arr2) {
    foreach (array_keys($arr2) as $a) {
        // perform whatever transformations you want on the key here
        $new_key = str_replace("-", " ", $a);
        // use the transformed string as the array key;
        // we still need to access the data in the original array, so store the outer
        // array key ("Administrator", "Analyst", etc.) and the inner array key
        // ("network-administrator", etc.) in a subarray.
        $t_keys[$new_key] = array( $k, $a );
    }
}

An example key-value pair from $t_keys:

$t_keys['network administrator'] = ['Administrator', 'network-administrator']

To access the value in the original array, we need to get $pages['Administrator']['network-administrator'], or, using the equivalent values from $t_keys: $pages[ $t_keys['network administrator'][0] ][ $t_keys['network administrator'][1] ].

To match against your search string:

$str = str_replace("-", " ", $original_search_string_from_url);

// check if it's in the transformed keys array
if (array_key_exists($str, $t_keys)) {
    // now we can access the data from our $pages array!
    $target = $pages[ $t_keys[$str][0] ][ $t_keys[$str][1] ];
    echo "the proper name for $str is " . $t_keys[$str][1] . "\n";
//  output: "the proper name for network administrator is network-administrator"

    // access various attributes of the network-administrator:
    echo "the title of $str is " . $target['title'];
}

If you don't need to know what the keys in $pages are (e.g. 'Administrator' and 'network-administrator') and just want to get straight to the relevant data, you could create references instead of storing the keys. Here's an example:

$refs = array();

foreach ($pages as $k => $arr2) {
    foreach (array_keys($arr2) as $a) {
        // perform whatever transformations you want on the key here
        $new_key = str_replace("-", " ", $a);
        // create a reference ( =& ) to the contents of $pages[$k][$a]
        // $refs[$new_key] points directly at $pages[$k][$a]
        $refs[$new_key] =& $pages[$k][$a];
    }
}

Now $refs['network administrator'] acts like a shortcut to $pages['Administrator']['network-administrator']; $refs['network administrator']['post'] accesses $pages['Administrator']['network-administrator']['post'], and so on.

i alarmed alien
  • 9,412
  • 3
  • 27
  • 40
  • References look cool, uses less code and doesn't need the string checker part of the code from your first example, am I correct? – Mike Sep 27 '14 at 21:56
  • got a question for you. It works great btw. I am trying to access the stripped characters version of the value in the array from your foreach loop. I can't figure it out. I know how to get the proper one by using `$t_keys[$str][1]` but what do I use to access the stripped version of that same array key? – Mike Sep 28 '14 at 02:53
  • The stripped version will be `$str`. If you want to have the stripped version available, you could add it to the data in the nested array -- e.g. in the loop that sets up the lookup table `$t_keys` or `$refs`, you could do (in the `$refs` version): `$refs[$new_key] =& $pages[$k][$a]; $pages[$k][$a]['stripped-key'] = $new_key;`. – i alarmed alien Sep 28 '14 at 16:47
  • you mentioned this in your answer above `If you don't need to know what the keys in $pages are`. Can you clarify that? I'm not using the Reference version yet because I'm unsure about it. I still need access to the to the keys in pages. – Mike Sep 28 '14 at 17:24
  • Sometimes you just want to get the information that is held in the innermost array--in this case, `title`, `post`, etc.--and you don't care about keys of the outer arrays--in this case, if you don't need to know that the outer array key is `Administrator` and the inner key is `network-administrator`. – i alarmed alien Sep 28 '14 at 17:30
  • so I won't be able to access the key itself to echo it on the screen? I don't get it. – Mike Sep 28 '14 at 17:35
  • I think I've managed to confuse you. There are different ways to approach this kind of problem, depending on what you want to do with the information you're dealing with. If the way that you're doing it is working and you have all the information you need, just go with that. Other techniques may be better suited to different situations. – i alarmed alien Sep 28 '14 at 17:42
  • no problem, what I have works. I'll eventually understand more clearly about references. I'll read up on it. Maybe you can help me with one last thing I need to implement in the loop above. I need to find partial matches of the string in the array. Shall I post another question with examples and link you? – Mike Sep 28 '14 at 17:45
  • here is the link to my new question if you would like to help me out again :) http://stackoverflow.com/questions/26088064/need-to-add-string-partial-match-look-up-in-foreach-loop-to-find-array-keys – Mike Sep 28 '14 at 18:23
  • how do I test for trueness for `$t_keys[$str][1]`? Meaning, if it is set and true? `isset($t_keys[$str][1])` turns it into 1. What about `!empty($t_keys[$str][1])` or `($t_keys[$str][1] == true)` or `($t_keys[$str][1] != '')` or `($t_keys[$str][1] != null)` I'm kinda stuck. Need to check if it is set and the key is really there as in, not just set, but is the value really there? – Mike Sep 29 '14 at 01:11
  • `$t_keys[$str][1]` should always be set as you created `$t_keys` from the existing hash. Generally, you can check for keys with `if (isset($array[$key1][$key2][$key3])) { ... }` – i alarmed alien Sep 29 '14 at 07:34
  • What I did was I put `$t_keys[$str][1]` into a variable called `$arrPosition` and I test it like this `if ($arrPosition == true)` or to test the non existence I do `if ($arrPosition != true)`. Is this the correct way to do it? $t_keys won't always be set because it is based on the string that comes from the query string. If no query string is there, then $t_keys is not built, am I correct? – Mike Sep 29 '14 at 07:39
  • `isset` is probably better than true, mostly because I think it makes more sense when reading through the code at a later date. There are numerous ways to check whether or not a variable is set (as you have seen!) so I go with the one that makes that most sense to me. – i alarmed alien Sep 29 '14 at 07:58