PHP çok boyutlu Array Sum / Silme Sorunu

3 Cevap php

Ben aşağıdaki gibi görünen bir dizi var:

Biçimi:

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

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
    )

Kelime "dizi" solunda sayısı, bir kişiyi ifade eder. İlk tek haneli bir numara bir banka temsil eder. Ikinci sayı bankada bir dengeyi temsil eder.

Ben bu örnekte, Banka # 2 Banka # 2 ile bir hesabınız varsa tüm insanlar için bir sıfır denge vardır göreceğiniz gibi, bir tabloda bu numaraları baskı ve ediyorum. Ve / veya Banka # 2 olmadan diziyi yeniden - Ben diziden Banka # 2 kaldırmak için bir yol gerekir. Tabii ki, her zaman (tüm insanlar arasında) sıfır toplam dengesi ile herhangi Bankalar bulur ve kaldırır bir çözüm olmak zorundadır bu yüzden kaldırılması gerekiyor Bank 2. olmayacaktır.

Alternatif olarak, ben tabloyu yazdırmak için gitmeden önce diziden tüm sıfır bakiye kaldırılması ile iyiyim.

Ben birini ya da yapmak için basit bir yol bulmak mümkün değil gibi kolay olduğu emin değilim.

3 Cevap

Yalnızca kullanılmayan bankalar çıkarılması kesinlikle sadece tüm sıfır dengeleri kaldırarak daha tricker olduğunu. İşte bankaların ortadan kaldırılması benim girişimi:

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]);
        }
    }
}

Çıktı:

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
        )

)

all sıfır balances gerçekten çok basit olurdu Çıkarma:

$array = array_map('array_filter', $array);

Bu deneyin:

<?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);
?>