Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
add comment

3 Answers

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
        )

)
share|improve this answer
add comment

Removing all zero balances would be very simple indeed:

$array = array_map('array_filter', $array);
share|improve this answer
    
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 Nov 1 '09 at 6:41
    
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 Nov 1 '09 at 6:45
    
@Ignas: Ah ok, cool, I missed that. :P –  o.k.w Nov 1 '09 at 6:47
add comment

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);
?>
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.