I have a user upload a .csv file from the backend of Wordpress through a custom file upload field (Advanced custom fields). I then call this field to retrieve the data from that file to create an array of said data:
$upload_cq = get_field('report_current_quarter');
$report_cq = array();
if(($handle_cq = fopen($upload_cq, "r")) !== FALSE)
{
while(($data_cq = fgetcsv($handle_cq, 1000, ",")) !== FALSE)
{
$report_cq[] = $data_cq;
}
$results_cq = array_slice($report_cq, 3); // remove unwanted row
fclose($handle_cq);
}
Once I create the array, I then create another array with a key and associate value, and ensure that the "team_id" column is present & not empty, as so (there is a teamName function which I won't get into):
foreach($results_cq as $results)
{
$team_id = $results[6];
if(!empty($team_id))
{
$team_totals_cq[] = array(
'id' => $team_id,
'team' => teamName($team_id),
'total_volume' => $results[41],
'total_closed' => $results[24],
'listings_closed' => $results[22],
'buyers_closed' => $results[23],
'total_agc' => $results[29],
'rental_agc' => $results[30],
);
}
}
echo '<pre>'; print_r($team_totals_cq); echo '</pre>';
When printing the array, I get the following. My question now is; How do I group results with the same team "id" and add up their results (results = total_volume, total_closed, listings_closed, buyers_closed, total_agc, and rental_agc):
Array
(
...
[6] => Array
(
[id] => 0011
[team] => Williamson Team
[total_volume] => $990,000
[total_closed] => 4
[listings_closed] => $0.00
[buyers_closed] => 1
[total_agc] => $20,812.50
[rental_agc] => $23,812.50
)
...
[9] => Array
(
[id] => 0011
[team] => Williamson Team
[total_volume] => $415,000
[total_closed] => 2
[listings_closed] => $0.00
[buyers_closed] => 0
[total_agc] => $12,450.00
[rental_agc] => $12,450.00
)
...
)
I have tried everything within my abilities, and nothing has worked.
One method is to use team_id as keys in $team_totals_cq then simply add up the values as you go through the loop.
(Note: The preg_replace function strips anything that aren't numbers or .)
$team_totals_cq = [];
foreach ($results_cq as $results) {
$team_id = $results[6];
if (!empty($team_id)) {
if (!isset($team_totals_cq[$team_id])) {
$team_totals_cq[$team_id] = [
'id' => $team_id,
'team' => teamName($team_id),
'total_volume' => preg_replace("/[^0-9\.]/", '', $results[41]),
'total_closed' => $results[24],
'listings_closed' => preg_replace("/[^0-9\.]/", '', $results[22]),
'buyers_closed' => $results[23],
'total_agc' => preg_replace("/[^0-9\.]/", '', $results[29]),
'rental_agc' => preg_replace("/[^0-9\.]/", '', $results[30])
];
} else {
$team_totals_cq[$team_id]['total_volume'] += preg_replace("/[^0-9\.]/", '', $results[41]);
$team_totals_cq[$team_id]['total_closed'] += $results[24];
$team_totals_cq[$team_id]['listings_closed'] += preg_replace("/[^0-9\.]/", '', $results[22]);
$team_totals_cq[$team_id]['buyers_closed'] += $result[23];
$team_totals_cq[$team_id]['total_agc'] += preg_replace("/[^0-9\.]/", '', $results[29]);
$team_totals_cq[$team_id]['rental_agc'] += preg_replace("/[^0-9\.]/", '', $results[30]);
}
}
}
Related
I have this array :
(
[id] => block_5df755210d30a
[name] => acf/floorplans
[data] => Array
(
[floorplans_0_valid_for_export] => 0
[floorplans_0_title] => title 1
[floorplans_0_house_area] => 40m²
[floorplans_0_bedrooms] => 1
[floorplans_1_valid_for_export] => 1
[floorplans_1_title] => title xx
[floorplans_1_house_area] => 90m²
[floorplans_1_bedrooms] => 2
[floorplans_2_valid_for_export] => 1
[floorplans_2_title] => title 2
[floorplans_2_house_area] => 50m²
[floorplans_2_bedrooms] => 1
[floorplans] => 3
)
)
As we can see in the data, we have fields (floorplans_X_valid_for_export).
What I want to do is to get the data only when this field equal to 1.
So from the given example, I want to keep only these fields:
[floorplans_1_valid_for_export] => 1
[floorplans_1_title] => title xx
[floorplans_1_house_area] => 90m²
[floorplans_1_bedrooms] => 2
[floorplans_2_valid_for_export] => 1
[floorplans_2_title] => title 2
[floorplans_2_house_area] => 50m²
[floorplans_2_bedrooms] => 1
This is an odd schema, but it can be done by iterating through the array and searching for keys where "valid_for_export" equals 1, and then using another array of field "stubs" to get the associated items by a unique identifier of X in floorplans_X_valid_for_export
$array = [
'floorplans_0_valid_for_export' => 0,
'floorplans_0_title' => 'title 1',
'floorplans_0_house_area' => '40m²',
'floorplans_0_bedrooms' => 1,
'floorplans_1_valid_for_export' => 1,
'floorplans_1_title' => 'title xx',
'floorplans_1_house_area' => '90m²',
'floorplans_1_bedrooms' => '2',
'floorplans_2_valid_for_export' => 1,
'floorplans_2_title' => 'title 2',
'floorplans_2_house_area' => '50m²',
'floorplans_2_bedrooms' => 1,
'floorplans' => 3
];
$stubs = [
'floorplans_%s_valid_for_export',
'floorplans_%s_title',
'floorplans_%s_house_area',
'floorplans_%s_bedrooms'
];
$newArr = [];
foreach ($array as $key => $value) {
if (strpos($key, 'valid_for_export') && $array[$key] == 1) {
$intVal = filter_var($key, FILTER_SANITIZE_NUMBER_INT);
foreach ($stubs as $stub) {
$search = sprintf($stub, $intVal);
if (isset($array[$search])) {
$newArr[$search] = $array[$search];
} else {
// key can't be found, generate one with null
$newArr[$search] = null;
}
}
}
}
echo '<pre>';
print_r($newArr);
Working: http://sandbox.onlinephpfunctions.com/code/23a225e3cefa2dc9cc97f53f1cbae0ea291672c0
Use a parent loop to check that the number-specific valid_for_export value is non-empty -- since it is either 0 or non-zero.
If so, then just push all of the associated elements into the result array.
Some reasons that this answer is superior to the #Alex's answer are:
Alex's parent loop makes 13 iterations (and the same number of strpos() calls); mine makes just 3 (and only 3 calls of empty()).
$array[$key] is more simply written as $value.
Sanitizing the $key to extract the index/counter is more overhead than necessary as demonstrated in my answer.
Code (Demo)
$array = [
'floorplans_0_valid_for_export' => 0,
'floorplans_0_title' => 'title 1',
'floorplans_0_house_area' => '40m²',
'floorplans_0_bedrooms' => 1,
'floorplans_1_valid_for_export' => 1,
'floorplans_1_title' => 'title xx',
'floorplans_1_house_area' => '90m²',
'floorplans_1_bedrooms' => '2',
'floorplans_2_valid_for_export' => 1,
'floorplans_2_title' => 'title 2',
'floorplans_2_house_area' => '50m²',
'floorplans_2_bedrooms' => 1,
'floorplans' => 3
];
$labels = ['valid_for_export', 'title', 'house_area', 'bedrooms'];
$result = [];
for ($i = 0; $i < $array['floorplans']; ++$i) {
if (!empty($array['floorplans_' . $i . '_valid_for_export'])) {
foreach ($labels as $label) {
$key = sprintf('floorplans_%s_%s', $i, $label);
$result[$key] = $array[$key];
}
}
}
var_export($result);
Output:
array (
'floorplans_1_valid_for_export' => 1,
'floorplans_1_title' => 'title xx',
'floorplans_1_house_area' => '90m²',
'floorplans_1_bedrooms' => '2',
'floorplans_2_valid_for_export' => 1,
'floorplans_2_title' => 'title 2',
'floorplans_2_house_area' => '50m²',
'floorplans_2_bedrooms' => 1,
)
With that constructed data it might be hard (not impossble tho), hovewer i would suggest to change it to multidimensional arrays so you have something like:
[floorplans][0][valid_for_export] => 0
[floorplans][0][title] => title 1
[floorplans][0][house_area] => 40m²
[floorplans][0][bedrooms] => 1
[floorplans][1][valid_for_export] => 1
[floorplans][1][title] => title xx
[floorplans][1][house_area] => 90m²
Rought sollution
It is not the best approach, but it should work if you dont need anything fancy, and know that structure of data wont change in future
$keys = [];
$for($i=0;$i<$array['floorplans'];++$i) {
if(isset($array['floorplans_'.$i.'_valid_for_export']) && $array['floorplans_'.$i.'_valid_for_export']===1) {
$keys[] = $i;
}
}
print_r($keys);
What I'm trying to accomplish is to write a html string in a controller with array values being looped in it. So for example;
$content = "Your store, at location A, has these items added to them". add array loop here. "Do take note!";
My array would be as such
array (
0 =>
array (
'id' => '5db29b6d31c391731239bbdf',
'name' => 'Diamond bracelet (sample)',
'tags' =>
array (
0 => 'female',
1 => 'jewelry',
),
'category' => 'Accessories',
'sku' => '1029EHW',
'priceType' => 'Fixed',
'unitPrice' => 190,
'cost' => 90,
'trackStockLevel' => true,
'isParentProduct' => false,
),
1 =>
array (
'id' => '5db29b6d31c391731239bbdb',
'name' => 'Long-sleeved shirt(sample)(M)',
'tags' =>
array (
0 => 'tops',
1 => 'cotton',
),
'category' => 'Women\'s Apparel',
'sku' => 'ABC1234-M',
'priceType' => 'Fixed',
'unitPrice' => 47.170000000000002,
'cost' => 20,
'trackStockLevel' => true,
'isParentProduct' => false,
'parentProductId' => '5db29b6d31c391731239bbd4',
'variationValues' =>
array (
0 =>
array (
'variantGroupId' => '5db29b6d31c391731239bbd5',
'value' => 'M',
),
),
),
)
note that the array can have many instances of product_name and sku, or can have none.
How do i populate this in my string to be like;
$content = "Your store, at location A, has these items added to them, 1) asd, 2)def, 3)asf . Do take note!
Try this, I've used \sprintf for ease, check if the output serves your purpose.
<?php
function stringMethod(): string
{
$count = 0;
$arrayString = [];
$array = [['product_name' => 'abc', 'product_sku' => 'def'],['product_name' => 'abc', 'product_sku' => 'asd']];
foreach ($array as $value){
$count++;
$arrayString[] = sprintf('%s)%s', $count, $value['product_sku']);
}
$string = \implode(',', $arrayString);
return \sprintf("Your store, at location A, has these items added to them %s Do take note!", $string);
}
echo stringMethod();
Hope this will help you. try to do it in less number of lines
$content = "Your store, at location A, has these items added to them, ";
$productArray = array (0 => array ('id' => '5db29b6d31c391731239bbdf','name' => 'Diamond bracelet (sample)','tags' => array (0 => 'female',1 => 'jewelry',),'category' => 'Accessories','sku' => '1029EHW','priceType' => 'Fixed','unitPrice' => 190,'cost' => 90,'trackStockLevel' => true,'isParentProduct' => false,),1 => array ('id' => '5db29b6d31c391731239bbdb','name' => 'Long-sleeved shirt(sample)(M)','tags' => array (0 => 'tops',1 => 'cotton',),'category' => 'Women\'s Apparel','sku' => 'ABC1234-M','priceType' => 'Fixed','unitPrice' => 47.170000000000002,'cost' => 20,'trackStockLevel' => true,'isParentProduct' => false,'parentProductId' => '5db29b6d31c391731239bbd4','variationValues' => array (0 => array ('variantGroupId' => '5db29b6d31c391731239bbd5','value' => 'M'))));
foreach ($productArray as $key => $product) {
$content .= ($key+1).') '.$product['name'];
if (count($productArray)-1!=$key) {
$content .= ', ';
}
}
$content .= ". Do take note!";
$content = "Your store, at location A, has these items added to them,". $this->getItemList($collection) .". Do take note!"
# Somewhere else in the controller
protected function getItemList(Collection $collection): string
{
return $collection->pluck('name')
->merge($collection->pluck('sku'))
->map(function($item, $key) {
return ($key + 1) . ') ' . $item;
})
->implode(', ');
}
An easy solution would be
$content = "Your store, at location A, has these items added to them";
$array = array(0=>["product_name" => "abc", "product_sku" => "def"], 1=>['product_name' => 'kdkf', 'product_sku'=> 'ljbkj']);
for($i = 0; $i<count($array); $i++){
$content .= ($i+1).") ".$array[$i]['product_name].' '.$array[$i]['product_sku'].', ';
}
$content .= "Do take note.";
This way you're just constantly concatonating the string value in separate parts instead of trying to inject it in the middle of the parent string.
not tested, may be syntax errors
I have an array that looks like this:
[0] => Array
(
[name] => typeOfMusic
[value] => this_music_choice
)
[1] => Array
(
[name] => myMusicChoice
[value] => 9
)
[2] => Array
(
[name] => myMusicChoice
[value] => 8
)
I would like to reform this into something with roughly the following structure:
Array(
"typeOfMusic" => "this_music_choice",
"myMusicChoice" => array(9, 8)
)
I have written the following but it doesn't work:
foreach($originalArray as $key => $value) {
if( !empty($return[$value["name"]]) ){
$return[$value["name"]][] = $value["value"];
} else {
$return[$value["name"]] = $value["value"];
}
}
return $return;
I've tried lots of different combinations to try and get this working. My original array could contain several sets of keys that need converting to arrays (i.e. it's not always going to be just "myMusicChoice" that needs converting to an array) ?
I'm getting nowhere with this and would appreciate a little help. Many thanks.
You just need to loop over the data and create a new array with the name/value. If you see a repeat name, then change the value into an array.
Something like this:
$return = array();
foreach($originalArray as $data){
if(!isset($return[$data['name']])){
// This is the first time we've seen this name,
// it's not in $return, so let's add it
$return[$data['name']] = $data['value'];
}
elseif(!is_array($return[$data['name']])){
// We've seen this key before, but it's not already an array
// let's convert it to an array
$return[$data['name']] = array($return[$data['name']], $data['value']);
}
else{
// We've seen this key before, so let's just add to the array
$return[$data['name']][] = $data['value'];
}
}
DEMO: https://eval.in/173852
Here's a clean solution, which uses array_reduce
$a = [
[
'name' => 'typeOfMusic',
'value' => 'this_music_choice'
],
[
'name' => 'myMusicChoice',
'value' => 9
],
[
'name' => 'myMusicChoice',
'value' => 8
]
];
$r = array_reduce($a, function(&$array, $item){
// Has this key been initialized yet?
if (empty($array[$item['name']])) {
$array[$item['name']] = [];
}
$array[$item['name']][] = $item['value'];
return $array;
}, []);
$arr = array(
0 => array(
'name' => 'typeOfMusic',
'value' => 'this_music_choice'
),
1 => array(
'name' => 'myMusicChoice',
'value' => 9
),
2 => array(
'name' => 'myMusicChoice',
'value' => 8
)
);
$newArr = array();
$name = 'name';
$value = 'value';
$x = 0;
foreach($arr as $row) {
if ($x == 0) {
$newArr[$row[$$name]] = $row[$$value];
} else {
if (! is_array($newArr[$row[$$name]])) {
$newArr[$row[$$name]] = array();
}
array_push($newArr[$row[$$name]], $row[$$value]);
}
$x++;
}
Here are two example of the format of the Arrays, full code and array content in my code below.
ARRAY 1
[
'version' => '1.0',
'injuries' => [
'timestamp' => 1377702112,
'week' => 1,
'injury' => [
[
'status' => 'Questionable',
'id' => '10009',
'details' => 'Shoulder'
],
[
'status' => 'Questionable',
'id' => '10012',
'details' => 'Ankle'
]
]
]
]
ARRAY 2
[
'version' => '1.0',
'players' => [
'timestamp' => 1377676937,
'player' => [
[
'position' => 'TMDL',
'name' => 'Bills, Buffalo',
'id' => '0251',
'team' => 'BUF'
],
[
'position' => 'TMDL',
'name' => 'Colts, Indianapolis',
'id' => '10009',
'team' => 'IND'
]
]
]
]
What I need to do is sort through both Arrays and finding matching values for the ID key. I need to then combine the values of both arrays into one array so I can print it out on screen. There is two API's provided, one for the injuries report with a player [id] key and the other for the Players Information with [id] keys. Here is how far I have gotten on this problem:
<?php
function injuries_report() {
//Get json files
$injuryData = file_get_contents('http://football.myfa...=1&callback=');
$playerData = file_get_contents('http://football.myfa...L=&W=&JSON=1');
//format json data into an array
$obj1 = json_decode($injuryData, true);
$obj2 = json_decode($playerData, true);
//return print_r($obj1); //print obj1 to see output
return print_r($obj2); //print obj2 to see output
}
?>
<!--get injuries report -->
<pre><?php injuries_report(); ?></pre>
Here's the working code, thanks to Chris:)
$injuryData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=injuries&L=&W=&JSON=1&callback=');
$array1 = json_decode($injuryData, true);
$playerData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=players&L=&W=&JSON=1');
$array2 = json_decode($playerData, true);
function map($x) {
global $array1;
if(isset($x['id'])) {
$id = $x['id'];
$valid = array_filter($array1['injuries']['injury'], create_function('$injury', 'return $injury["id"] == "' . $id .'";'));
if(count($valid) > 0) {
$x = array_merge($x, array_shift($valid));
}
}
return $x;
}
$output = array_map('map', $array2['players']['player']);
echo "<pre>";
print_r($output);
echo "</pre>";
Ok, I'm assuming you want to add injuries to players. The output will be the list of players, with the injuries added (where they apply)
$output = array_map(function($x) use ($array1) {
$id = $x['id'];
$valid = array_filter($array1['injuries']['injury'], function($injury) use ($id) {
return $injury['id'] == $id;
});
if(count($valid) > 0) {
$x = array_merge($x, $valid[0]);
}
return $x;
}, $array2['players']['player']);
print_r($output);
The output is this:
Array
(
[0] => Array
(
[position] => TMDL
[name] => Bills, Buffalo
[id] => 0251
[team] => BUF
)
[1] => Array
(
[position] => TMDL
[name] => Colts, Indianapolis
[id] => 10009
[team] => IND
[status] => Questionable
[details] => Shoulder
)
)
php 5.2
Edit The latest working version:
Oh you are using php 5.2. Here is a php 5.2 version, but it less pretty than the code before:
$injuryData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=injuries&L=&W=&JSON=1&callback=');
$array1 = json_decode($injuryData, true);
$playerData = file_get_contents('http://football.myfantasyleague.com/2013/export?TYPE=players&L=&W=&JSON=1');
$array2 = json_decode($playerData, true);
function map($x) {
global $array1;
if(isset($x['id'])) {
$id = $x['id'];
$valid = array_filter($array1['injuries']['injury'], create_function('$injury', 'return $injury["id"] == "' . $id .'";'));
if(count($valid) > 0) {
$x = array_merge($x, array_shift($valid));
}
}
return $x;
}
$output = array_map('map', $array2['players']['player']);
print_r($output);
The $array1 is global here. Check it here: http://pastebin.com/N3RqtfzN
I have an array of items:
array(
[0] => array(
'item_no' => 1
'item_name' => 'foo
)
[1] => array(
'item_no' => 2
'item_name' => 'bar'
)
) etc. etc.
I am getting another array from a third party source and need to remove items that are not in my first array.
array(
[0] => array(
'item_no' => 1
)
[1] => array(
'item_no' => 100
) # should be removed as not in 1st array
How would I search the first array using each item in the second array like (in pseudo code):
if 'item_no' == x is in 1st array continue else remove it from 2nd array.
// Returns the item_no of an element
function get_item_no($arr) { return $arr['item_no']; }
// Arrays of the form "item_no => position in the array"
$myKeys = array_flip(array_map('get_item_no', $myArray));
$theirKeys = array_flip(array_map('get_item_no', $theirArray));
// the part of $theirKeys that has an item_no that's also in $myKeys
$validKeys = array_key_intersect($theirKeys, $myKeys);
// Array of the form "position in the array => item_no"
$validPos = array_flip($validKeys);
// The part of $theirArray that matches the positions in $validPos
$keptData = array_key_intersect($theirArray, $validPos);
// Reindex the remaining values from 0 to count() - 1
return array_values($keptData);
All of this would be easier if, instead of storing the key in the elements, you stored it as the array key (that is, you'd be using arrays of the form "item_no => item_data") :
// That's all there is to it
return array_key_intersect($theirArray, $myArray);
You can also do:
$my_array =array(
0 => array( 'item_no' => 1,'item_name' => 'foo'),
1 => array( 'item_no' => 2,'item_name' => 'bar')
);
$thrid_party_array = array(
0 => array( 'item_no' => 1),
1 => array( 'item_no' => 100),
);
$temp = array(); // create a temp array to hold just the item_no
foreach($my_array as $key => $val) {
$temp[] = $val['item_no'];
}
// now delete those entries which are not in temp array.
foreach($thrid_party_array as $key => $val) {
if(!in_array($val['item_no'],$temp)) {
unset($thrid_party_array[$key]);
}
}
Working link
If your key is not actually a key of your array but a value, you will probably need to do a linear search:
foreach ($itemsToRemove as $itemToRemove) {
foreach ($availableItems as $key => $availableItem) {
if ($itemToRemove['item_no'] === $availableItem['item_no']) {
unset($availableItems[$key]);
}
}
}
It would certainly be easier if item_no is also the key of the array items like:
$availableItems = array(
123 => array(
'item_no' => 123,
'item_name' => 'foo'
),
456 => array(
'item_no' => 456,
'item_name' => 'bar'
)
);
With this you could use a single foreach and delete the items by their keys:
foreach ($itemsToRemove as $itemToRemove) {
unset($availableItems[$itemToRemove['item_no']]);
}
You could use the following to build an mapping of item_no to your actual array keys:
$map = array();
foreach ($availableItems as $key => $availableItem) {
$map[$availableItems['item_no']] = $key;
}
Then you can use the following to use the mapping to delete the corresponding array item:
foreach ($itemsToRemove as $itemToRemove) {
unset($availableItems[$map[$itemToRemove['item_no']]]);
}