Reputation: 1849
I have an array that looks like this:
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) )
There's two things I need to do here:
1. get the count of all the specific fruits in the city (i.e. how many apples, oranges, lichies are there in total in city 309) and
2. How do I grab the values for a specific store?
Thanks in advance!
Upvotes: 1
Views: 260
Reputation: 7470
NOTE: Before any reaction… I know the OP has not asked how to handle this in an object-oriented fashion so this is just a suggestion.
I would create a separate class for the overall data and another for each store data.
$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;
}
}
will output
total products: 242
total products in city #309: 242
"apples" everywhere: 72
"apples" in store #12: 21
"apples" in city #309: 72
Upvotes: 0
Reputation: 441
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 ) );
Which would yield the following results...
Single City
Array
(
[city] => 309
[store] => 16
[apples] => 0
[oranges] => 0
[lichis] => 12
)
Totals
Array
(
[apples] => 72
[oranges] => 86
[lichis] => 84
)
Upvotes: 0
Reputation: 3633
This is a more complicated example, but better than spaghetti code. Turn your array into XML first.
// 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 ),
);
Writing spaghetti code to manually isolate stores becomes a messy jungle of if statements and loops.
// 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 );
}
At this point, $xml
looks like this (as a string) and is more manageable:
<xml>
<entry>
<city>309</city>
<store>12</store>
<apples>21</apples>
<oranges>14</oranges>
<lichis>34</lichis>
</entry>
...(more entries)...
</xml>
Now, load it into something queriable with XPath, an XML standard:
$xml = simplexml_load_string( array_to_xml( $my_array ) );
To get the count of all the specific fruits in the city (i.e. how many apples, oranges, lichies are there in total in city 309) we need a simple but reusable summary function.
// 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 );
}
We only want city 309, and looking specifically for apples, oranges and lichis, since they are fruits:
$only_this_city = $xml->xpath("//entry[city=309]");
print_r( count_items( $only_this_city, array("apples", "oranges", "lichis")) );
We get this:
Array
(
[apples] => 72
[oranges] => 86
[lichis] => 84
)
Secondly, to grab the values for a specific store:
$only_this_store = $xml->xpath("//entry[city=309 and store=14]");
print_r( count_items( $only_this_store, array("apples") ) );
You get:
Array
(
[apples] => 44
)
Obviously you can request more items, or query with more complexity. Look up some docs on XPath for future queries.
Upvotes: 0
Reputation: 1157
ok say the array is called $store
$count = 0;
$s = array();
foreach($store as $store){
$count = 0;
$count += $store['apples'];
$count += $store['oranges'];
$s[$store['store']] = $count;
}
add more fruit if needed.
Upvotes: 2