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
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.
Link to comment
Share on other sites

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.
Link to comment
Share on other sites

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]
Link to comment
Share on other sites

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