Jump to content

[SOLVED] An unusual array puzzle.


trq

Recommended Posts

Its been a long time since Ive had to post a question on this forum, and this is one that could probably go in the [i]PHP Challenge[/i] thread but I'm gonna post it here and see how we go.

I have a slightly unusual problem. I have three arrays...

[code=php:0]
$global = array('a','b','c','d');
$local = array('b','-c','-d');
$user = array('e','c','f');
[/code]

There three arrays are meant to represent a tree of user settings. The first ($global) are the defaults, these can then be overwritten by $local and $user while $global and $local can be overwritten by $user.. Notice the values starting with - (eg -c) in $local? This meens that the values c and d need to be removed from $global. Notice there is extra values (e and f) defined in $user? These need to be added to the final array.

Its kind of hard to explain, but I hope someone uderstands. the final array I need to make from these three arrays would contain the values a b c e f.

Here is one of my many attempts, but I'm just not getting the logic here. This code is also outputting warning about invalid array indexes on lines 28 and 29. I know what the problem is there, but really, the logic here just isn't working.

Anyone care to have a crack at this puzzle?

[code]
#!/usr/bin/php
<?php

    $global    = array('a','b','c','d');
    $local    = array('b','-c','-d');
    $user    = array('e','c','f');

    # expected results - a b c e f
   
    function cleanuse($g,$l,$u) {

        print_r($g);
        print_r($l);
        print_r($u);
   
        foreach ($u as $user) {
            if (substr($user,0,1) == '-') {
                unset($l[array_keys($l,$user)]);
                unset($l[array_keys($l,substr($user,1))]);
                unset($g[array_keys($g,$user)]);
                unset($g[array_keys($g,substr($user,1))]);
            }
        }

        foreach ($l as $local) {
            if (substr($local,0,1) == '-') {
                unset($g[array_keys($g,$local)]);                    # line 28
                unset($g[array_keys($g,substr($local,1))]);    # line 29 
            }
        }

        print_r($g);
        print_r($l);
        print_r($u);

        $tmp = array_merge($g,$l,$u);
        $return = array_unique($tmp);

        print_r($return);

    }

    cleanuse($global,$local,$user);

?>
[/code]
Link to comment
https://forums.phpfreaks.com/topic/36475-solved-an-unusual-array-puzzle/
Share on other sites

The problem is, that array_keys returns an array.
So you need to do something like this (will take the first loop as an example):

[code]<?php
foreach ($u as $user)
{
if (substr($user,0,1) == '-')
{
$key = array_keys($l,$user);
unset($l[key[0]]);
$key = array_keys($l,substr($user,1));
unset($l[$key]);
$key = array_keys($g,$user);
unset($g[$key[0]]);
$key = array_keys($g,substr($user,1))
unset($g[$key[0]]);
    }
}
?>[/code]

I think this is a start :D

Orio.
Ok... thats still not working. I think its because when I use unset, its obviously moving key positions around.

I think I need to rethink the logic completely. [url=http://www.thorpesystems.com/cleanuse.phps]here[/url] is a link to my latest changes (Sorry about the indentation, must be a bug in th eway phps works).

Anyway... I'm off to do some real work. I'll have a think about this and be back.
I got it working but its ugly as sin, look at all those loops. There MUST be a better way. I'm think recursion maybe but one again, the logic eludes me.

[code]
#!/usr/bin/php
<?php

    $global    = array('a','b','c','d');
    $local    = array('b','-c','-d');
    $user    = array('e','c','f');

    function cleanuse($g,$l,$u) {
        $rm = array();   
        foreach ($u as $user) {
            if (substr($user,0,1) == '-') {
                $rm[] = substr($user,1);
            }
        }
        foreach ($rm as $remove) {
            if (in_array($remove,$l)) {
                $key = array_keys($l,$remove);
                unset($l[$key[0]]);
            }
            if (in_array($remove,$g)) {
                $key = array_keys($g,$remove);
                unset($g[$key[0]]);
            }
        }
   
        foreach ($l as $local) {
            if (substr($local,0,1) == '-') {
                $rm[] = substr($local,1);
            }
        }
        foreach ($rm as $remove) {
            if (in_array($remove,$g)) {
                $key = array_keys($g,$remove);
                unset($g[$key[0]]);
            }
        }

        $tmp = array_merge($g,$l,$u);
        foreach ($tmp as $all) {
            if (substr($all,0,1) != '-') {
                $return[] = $all;
            }
        }
        return array_unique($return);
    }

    print_r(cleanuse($global,$local,$user));

?>
[/code]
You can minimize the number of lines, but I think the way you are doing it is one of the fastest. Recursion with php is very slow...
Here's a shorter version, basically doing the same thing, I don't know if it's more effective:

[code]<?php

$global = array('a','b','c','d');
$local = array('b','-c','-d');
$user = array('e','c','f');

function cleanuse($g,$l,$u)
{

foreach ($u as $user) //user filter
{
if (substr($user,0,1) == '-')
{
$char = substr($user,1);
if (count($key = array_keys($l,$char)) != 0)
unset($l[$key[0]]);
if (count($key = array_keys($g,$char)) != 0)
unset($g[$key[0]]);
}
}


foreach ($l as $local) //local filter
{
if (substr($local,0,1) == '-' && count($key = array_keys($g,substr($local,1))) != 0)
unset($g[$key[0]]);
}

$tmp = array_merge($g,$l,$u);
$return = array();
foreach ($tmp as $all)
{
if (substr($all,0,1) != '-')
$return[] = $all;
}

return array_unique($return);
}

print_r(cleanuse($global,$local,$user));

?>[/code]

Orio.

P.S- I tested it and it gave the same output

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.