如何计算PHP中多维数组中特定键的值?

时间:2013-01-08 14:29:49

标签: php arrays multidimensional-array

我有一个如下所示的数组:

  

阵列(
    [0] =>数组([city] => 309 [商店] => 12 [苹果] => 21 [橙子] => 14 [lichis] => 34)
    [1] =>数组([city] => 309 [商店] => 13 [苹果] => 0 [橙子] => 11 [lichis] => 32)
    [2] =>数组([city] => 309 [商店] => 14 [苹果] => 44 [橙子] => 61 [lichis] => 0)
    [3] =>数组([city] => 309 [商店] => 15 [苹果] => 7 [橙子] => 0 [lichis] => 6)
    [4] =>数组([city] => 309 [商店] => 16 [苹果] => 0 [橙子] => 0 [lichis] => 12)     )

我需要在这里做两件事:
 1.得到城市中所有特定水果的数量(即城市309中总共有多少苹果,橙子和荔枝)和
2.如何获取特定商店的值?

提前致谢!

4 个答案:

答案 0 :(得分:2)

好吧说这个数组叫做$ store

$count = 0;
$s = array();

foreach($store as $store){
 $count = 0;
 $count += $store['apples'];
 $count += $store['oranges'];

 $s[$store['store']] = $count;
}

如果需要,可以添加更多水果。

答案 1 :(得分:0)

这是一个更复杂的例子,但比意大利面条代码更好。首先将数组转换为XML。

// this is your initial array
$my_array = array(
array("city"=>309, "store"=>12, "apples"=>21, "oranges"=>14, "lichis"=>34 ),
array("city"=>309, "store"=>13, "apples"=>0, "oranges"=>11, "lichis"=>32 ),
array("city"=>309, "store"=>14, "apples"=>44, "oranges"=>61, "lichis"=>0 ),
array("city"=>309, "store"=>15, "apples"=>7, "oranges"=>0, "lichis"=>6 ),
array("city"=>309, "store"=>16, "apples"=>0, "oranges"=>0, "lichis"=>12 ),
);

编写意大利面条代码以手动隔离商店成为if语句和循环的混乱丛林。

// might as well convert it to xml
function array_to_xml( $data ) {
    $xml = "<xml>\n";
    foreach( $data as $row ) {
        $xml .= "<entry>";
        foreach( $row as $k => $v ) {
            $xml .= "<{$k}>{$v}</{$k}>";
        }
        $xml .= "</entry>\n";
    }
    $xml .= "</xml>\n";
    return( $xml );
}

此时,$xml看起来像这样(作为字符串)并且更易于管理:

<xml>
  <entry>
    <city>309</city>
    <store>12</store>
    <apples>21</apples>
    <oranges>14</oranges>
    <lichis>34</lichis>
  </entry>
  ...(more entries)...
</xml>

现在,使用XPath(XML标准)将其加载到可查询的内容中:

$xml = simplexml_load_string( array_to_xml( $my_array ) );

为了获得城市中所有特定水果的数量(即309城市中有多少苹果,橘子和脂肪),我们需要一个简单但可重复使用的汇总功能。

// so lets make a generic function to count specific items
function count_items( $stores, $items = array() ) {
    $sum = array();
    foreach( $stores as $store ) {
        foreach( $items as $k ) {
            if( !isset( $sum[$k] ) ) $sum[$k] = 0;
            $sum[$k] += $store->$k;
        }
    }
    return( $sum );
}

我们只想要309号城市,专门寻找苹果,橙子和荔枝,因为它们是水果:

$only_this_city = $xml->xpath("//entry[city=309]");
print_r( count_items( $only_this_city, array("apples", "oranges", "lichis")) );

我们得到了这个:

Array
(
    [apples] => 72
    [oranges] => 86
    [lichis] => 84
)

其次,要获取特定商店的值:

$only_this_store = $xml->xpath("//entry[city=309 and store=14]");
print_r( count_items( $only_this_store, array("apples") ) );

你得到:

Array
(
    [apples] => 44
)

显然,您可以请求更多项目,或查询更复杂。在XPath上查找一些文档以供将来查询。

答案 2 :(得分:0)

function extractData( array $data, $store = null )
{
    $callback = function( $values, $array ) use ( $store )
    {
        // We require values for a particular store
        if( ! is_null( $store ) )
        {
            if( $array[ 'store' ] == $store )
            {
                return $array;
            }

            return false;
        }
        // Return the sum of all stores in a city
        else
        {
            // Toss out the city and store values since they're not needed
            unset( $array['city'], $array['store'] );

            // Seed the initial values
            if( ! is_array( $values ) || empty( $values ) )
            {
                return $array;
            }

            // array_map function used add the arrays
            $add = function( $a, $b )
            {
                return $a + $b;
            };

            // Add the arrays
            $summedArray = array_map( $add, $values, $array );

            // Return the combined array structure
            return array_combine( array_keys( $values ), $summedArray );
        }
    };

    return array_reduce( $data, $callback, array() );
}

$data = array(
    0 => array(
        "city" => 309,
        "store" => 12,
        "apples" => 21,
        "oranges" => 14,
        "lichis" => 34
    ),
    1 => array(
        "city" => 309,
        "store" => 13,
        "apples" => 0,
        "oranges" => 11,
        "lichis" => 32
    ),
    2 => array(
        "city" => 309,
        "store" => 14,
        "apples" => 44,
        "oranges" => 61,
        "lichis" => 0
    ),
    3 => array(
        "city" => 309,
        "store" => 15,
        "apples" => 7,
        "oranges" => 0,
        "lichis" => 6
    ),
    4 => array(
        "city" => 309,
        "store" => 16,
        "apples" => 0,
        "oranges" => 0,
        "lichis" => 12
    )
);

// Return the values for a particular store
print_r( extractData( $data, 16 ) );

// Return the total of all stores in the city
print_r( extractData( $data ) );

哪会产生以下结果......

单一城市

Array
(
    [city] => 309
    [store] => 16
    [apples] => 0
    [oranges] => 0
    [lichis] => 12
)

<强>总计

Array
(
    [apples] => 72
    [oranges] => 86
    [lichis] => 84
)

答案 3 :(得分:0)

  

注意:在任何反应之前...我知道OP没有询问如何以面向对象的方式处理这个问题,所以这只是一个建议。

我会为整个数据创建一个单独的类,为每个商店数据创建另一个类。

$arr = array(
    array('city' => 309, 'store' => 12, 'apples' => 21, 'oranges' => 14, 'lichis' => 34),
    array('city' => 309, 'store' => 13, 'apples' => 0, 'oranges' => 11, 'lichis' => 32),
    array('city' => 309, 'store' => 14, 'apples' => 44, 'oranges' => 61, 'lichis' => 0),
    array('city' => 309, 'store' => 15, 'apples' => 7, 'oranges' => 0, 'lichis' => 6),
    array('city' => 309, 'store' => 16, 'apples' => 0, 'oranges' => 0, 'lichis' => 12)
);

foreach ($arr as $rec) {
    $storeID = $rec['store'];
    $city = $rec['city'];
    unset($rec['city'],$rec['store']);
    // assuming all the keys except these 2
    // represent product name->quantity pairs
    StoreData::add(new Store($storeID,$city,$rec));
}
//print_r(StoreData::$stores);

echo
'<b>total products:</b> ' .
    StoreData::get_total_products() . PHP_EOL .
'<b>total products in city #309:</b> ' .
    StoreData::get_total_products_by_city(309) . PHP_EOL .
'<b>"apples" everywhere:</b> ' .
    StoreData::get_product_total('apples') . PHP_EOL .
'<b>"apples" in store #12:</b> ' .
    StoreData::get_product_total_by_store('apples',12) . PHP_EOL .
'<b>"apples" in city #309:</b> ' .
    StoreData::get_product_total_by_city('apples',309);


class StoreData {

    public static $stores = array();

    public static function add(Store $store) {
        self::$stores[] = $store;
    }

    public static function remove(Store $store) {
        foreach (self::$stores as $key => $value) {
            if ($value == $store) {
                unset(self::$stores[$key]);
                break;
            }
        }
    }

    public static function find_by_city($cityID) {
        $cityID = (int) $cityID;
        return array_filter(self::$stores,create_function(
            '$store',
            "return \$store->city == $cityID;")
        );
    }

    public static function find_by_store($storeID) {
        $storeID = (int) $storeID;
        foreach (self::$stores as $store) {
            if ($store->id == $storeID) return $store;
        }
        return FALSE;
    }

    public static function get_total_products() {
        $total = 0;
        foreach (self::$stores as $store)
            $total += $store->get_total_products();
        return $total;
    }

    public static function get_total_products_by_city($city) {
        $stores = self::find_by_city((int) $city);
        $total = 0;
        foreach ($stores as $store)
            $total += $store->get_total_products();
        return $total;
    }

    public static function get_product_total_by_city($productName,$city) {
        return self::product_total($productName,self::find_by_city((int) $city));
    }

    public static function get_product_total_by_store($productName,$storeID) {
        $res = self::find_by_store((int) $storeID);
        return $res ? self::product_total($productName,array($res)) : $res;
    }

    public static function get_product_total($productName) {
        return self::product_total($productName,self::$stores);
    }

    private static function product_total($productName,$stores=NULL) {
        $total = 0;
        foreach ($stores as $store)
            $total += $store->get_product_total($productName);
        return $total;
    }

}

class Store {

    public $id;
    public $city;
    public $products;

    function __construct($id,$city,$products=array()) {
        $this->id = $id;
        $this->city = $city;
        $this->products = $products;
    }

    public function get_total_products() {
        return array_sum($this->products);
    }

    public function get_product_total($productName) {
        if (isset($this->products[$productName]))
            return (int) $this->products[$productName];
        return 0;
    }

}

将输出

  

总产品: 242
  城市#309中的总产品: 242
  到处都是“苹果”: 72
  商店#12中的“苹果”: 21
  城市中的“苹果”#309: 72