views:

339

answers:

4

Hi, I have an array that looks like the following:

The format:

[Person#] => Array
    (
        [Bank#] => Balance
        .
        .
        [Bank#] => Balance
    )

The Array:

[1] => Array
    (
        [0] => 707  //Person #1 has 707 balance in Bank #0
        [1] => 472  //Person #1 has 472 balance in Bank #1 
    )
[2] => Array
    (
        [0] => 2614
        [3] => 140
        [1] => 2802
        [4] => 245
        [2] => 0    //Person #2 has 0 balance in Bank #2
    )

[3] => Array
    (
        [2] => 0
        [3] => 0
        [0] => 1710
        [4] => 0
        [1] => 575
    )

[4] => Array
    (
        [1] => 1105
        [0] => 1010
        [4] => 0
        [3] => 120
        [2] => 0
    )

[5] => Array
    (
        [1] => 238
        [4] => 0
        [0] => 0
    )

[6] => Array
    (
        [0] => 850
        [1] => 0
    )

[7] => Array
    (
        [4] => 500
        [0] => 3397
        [1] => 2837
    )

The number to the left of the word "Array" represents a person. The first single digit number represents a bank. The second number represents a balance in the bank.

I'm printing these numbers out in a table and, as you'll see in this example, Bank #2 has a zero balance for all people who have an account with Bank #2. I need a way to remove Bank #2 from the array -- and/or recreate the array without Bank #2. Of course, it won't always be Bank #2 that needs to be removed so it has to be a solution that finds any Banks with a total balance of zero (across all people) and removes it.

Alternatively, I am fine with removing all zero balances from the array before going to print out the table.

I'm not sure which is easier as I haven't been able to find a simple way to do either one.

+1  A: 

Removing all zero balances would be very simple indeed:

$array = array_map('array_filter', $array);
Ignas R
The OP wants to remove those bank accounts for `SUM(Bank for all account) = 0`. Does `array_filter` do that? Will it retain Person3's Bank3 account?
o.k.w
No, but he says "Alternatively, I am fine with removing all zero balances from the array before going to print out the table".
Ignas R
@Ignas: Ah ok, cool, I missed that. :P
o.k.w
+1  A: 

Removing only unused banks is definitely tricker than just removing all zero balances. Here's my attempt at eliminating the banks:

for ($bank = 0; ; ++$bank) {
    $bankUsed = null;

    foreach ($balances as $customer) {
        if (isset($customer[$bank])) {
            $bankUsed = false;

            if ($customer[$bank] > 0) {
                $bankUsed = true;
                break;
            }
        }
    }

    if ($bankUsed === null) {
        echo "Bank $bank not found. Exiting.\n";
        break;
    }
    else if ($bankUsed === false) {
        echo "Bank $bank unused.\n";

        foreach ($balances as &$customer) {
            unset($customer[$bank]);
        }
    }
}

Output:

Bank 2 unused.
Bank 5 not found. Exiting.
Array
(
    [1] => Array
        (
            [0] => 707
            [1] => 472
        )

    [2] => Array
        (
            [0] => 2614
            [3] => 140
            [1] => 2802
            [4] => 245
        )

    [3] => Array
        (
            [3] => 0
            [0] => 1710
            [4] => 0
            [1] => 575
        )

    [4] => Array
        (
            [1] => 1105
            [0] => 1010
            [4] => 0
            [3] => 120
        )

    [5] => Array
        (
            [1] => 238
            [4] => 0
            [0] => 0
        )

    [6] => Array
        (
            [0] => 850
            [1] => 0
        )

    [7] => Array
        (
            [0] => 850
            [1] => 0
        )

)
John Kugelman
A: 

Cool, that worked perfectly (although SO logged me into another account when I tried to register that name... this is the same guy) <- referring to the first guy to respond.

Haven't tried the bank removing one yet but I'll try it out now.

TightPoker
@TightPoker (aka natarem): You'll need to add the above as a comment, not an answer :)
o.k.w
StackExchange software doesn't allow me to add a comment on the solutions above...
TightPoker
+1  A: 

Try this:

<?php
error_reporting(E_ALL | E_STRICT);

header('Content-Type: text/plain');

// subset of initial data
$persons = array(
  '1' => array(0 => 707, 1 => 472),
  '2' => array(0 => 2614, 3 => 140, 1 => 2802, 4 => 245, 2 => 0),
  '3' => array(2 => 0, 3 => 0, 0 => 1710, 4 => 0, 1 => 575),
);

// build a table of bank => balances
$banks = array();
foreach ($persons as $person => $balances) {
  foreach ($balances as $bank => $balance) {
    $banks[$bank][$balance] = true;
  }
}

// remove 0 balances from the balances of each bank
// if the balances array for that bank is then empty
// then only 0 balances were there and we can remove it
$can_remove = array();
foreach ($banks as $bank => $balances) {
  unset($balances[0]);
  if (count($balances) == 0) {
    $can_remove[] = $bank;
  }
}

// go through and remove the banks that can
// be removed. Note: we have to traverse the
// array by *reference* because otherwise you
// are modifying a copy of the array (which is
// then discarded) instead of the actual array.
foreach ($persons as $person => &$balances) {
  foreach ($can_remove as $bank) {
    unset($balances[$bank]);
  }
}
print_r($persons);
?>
cletus