Associative Array with Variable Values - php

I have been looking all over the place for what i need but i'm not getting anywhere. Not sure if it is because the thing i want isn't allowed or i just don't' know how to word it properly to find the solution.
I am creating a excel export that has a lot of worksheets so there is a lot of repetitive code so I made a foreach loop. The problem is the array i have has variables inside it and i need the code to put those specific variables to the spots i need it.
$y1953 =& $workbook->add_worksheet('1953');
$y1958 =& $workbook->add_worksheet('1958');
$y1963 =& $workbook->add_worksheet('1963');
$y1978 =& $workbook->add_worksheet('1978');
$y1988 =& $workbook->add_worksheet('1988');
$y2003 =& $workbook->add_worksheet('2003');
$yearlist = array($y1953 => '1953', $y1958 => '1958', $y1963 => '1963', $y1978 => '1978', $y1988 => '1988', $y2003 => '2003');
foreach ($yearlist as $year => $yearnum){
$line = 1; # Start on line 2
# Write each line
foreach ($bll->rows AS $row) {
$numberlist = array (''=>'1', '2'=>'2', '3' => '3', '4' => '4');
foreach ($numberlist as $name => $num){
if ($row['gYear'.$name] === $yearnum){
$col = 0;
$year->write_string($line, $col, ''); $col += 1;
$year->write_string($line, $col, $row['name_last'.$name]);$col += 1;
$year->write_string($line, $col, $row['name_first'.$name]); $col += 1;
$year->write_string($line, $col, $row['name_last']); $col +=1;
if($row['session'. $num .'1'] === '1')
{
$year->write_number($line, $col, $row['session'. $num .'1'] );
}$col += 1;
if($row['session'. $num .'2'] === '1')
{
$year->write_number($line, $col, $row['session'. $num .'2'] );
}$col += 1;
if($row['session'. $num .'3'] === '1')
{
$year->write_number($line, $col, $row['session'. $num .'3'] );
}$col += 1;
if($row['session'. $num .'4'] === '1')
{
$year->write_number($line, $col, $row['session'. $num .'4'] );
}$col += 1;
if($row['session'. $num .'5'] === '1')
{
$year->write_number($line, $col,$row['session'. $num .'5'] );
}$col += 1;
if($row['session'. $num .'6'] === '1')
{
$year->write_number($line, $col, $row['session'. $num .'6'] );
}$col += 1;
$year->write_number($line, $col, '1'); $col +=1;
$year->write_string($line, $col, $row['notes']); $col += 1;
$line += 1;
}
}
}
$yearlist is the array that i am having trouble with. I need the first value "$y1953" to be where $year is in the foreach loop. Right now, nothing shows up in my excel sheet.
So is there a way to have the code just put the variable in the spot i need it? Or could it be the variables values?
I would do this differently but the person I am making this excel export for wants it a specific way.
Thanks

Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.
http://php.net/manual/en/language.types.array.php
Try switching the keys and values around in your array declaration.
$yearlist = array('1953' => $y1953, '1958' => $y1958......etc.
Than change your foreach to
foreach ($yearlist as $yearnum => $year)

Maybe, you could create a worksheet inside the loop. Instead of:
$y1953 =& $workbook->add_worksheet('1953');
$y1958 =& $workbook->add_worksheet('1958');
$y1963 =& $workbook->add_worksheet('1963');
$y1978 =& $workbook->add_worksheet('1978');
$y1988 =& $workbook->add_worksheet('1988');
$y2003 =& $workbook->add_worksheet('2003');
$yearlist = array($y1953 => '1953', $y1958 => '1958',
$y1963 => '1963', $y1978 => '1978', $y1988 => '1988',
$y2003 => '2003');
Try this:
$yearlist = array('1953', '1958', '1963', '1978', '1988', '2003');
foreach($yearlist as $value)
{
$sheet =& $workbook->add_worksheet($value);
//do the job with the year and new worksheet
}

Related

How to sum nested array or variables from children and parent [duplicate]

I have an array like this:
Array
(
[1000] => Array
(
[pv] => 36
)
[1101] => Array
(
[1102] => Array
(
[pv] => 92
)
[pv] => 38
)
[pv] => 64
)
How I can find the sum of all array elements with key 'pv', regardless of the depth at which they appear?
For this example the result will be 36+92+38+64 = 230
Another alternative:
$sum = 0;
$array_obj = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($array_obj as $key => $value) {
if($key == 'pv')
$sum += $value;
}
echo $sum;
Update: Just thought I'd mention that this method uses the PHP SPL Iterators.
Salathe Edit:
A simple (relatively) way to filter the keys and to sum the values (without writing a custom Iterator) would be to do some filtering with a RegexIterator, convert the resulting iterator into an array and use the handy array_sum function on it. This is purely an academic exercise and I certainly wouldn't advocate it as the best way to achieve this... however, it is just one line-of-code. :)
$sum = array_sum(
iterator_to_array(
new RegexIterator(
new RecursiveIteratorIterator(
new RecursiveArrayIterator($array)
),
'/^pv$/D',
RegexIterator::MATCH,
RegexIterator::USE_KEY
),
false
)
);
function addPV($array){
$sum = 0;
foreach($array as $key => $a){
if (is_array($a)){
$sum += addPV($a);
}else if($key == 'pv') {
$sum += $a;
}
}
return $sum;
}
based on #Ali Sattari answer
function sum($v, $w) {
return $v + (is_array($w) ?
array_reduce($w, __FUNCTION__) : $w);
}
you can use array_reduce or array_walk_recursive functions and a custom call back function of yourself:
function sum($v, $w)
{
$v += $w;
return $v;
}
$total = array_reduce($your_array, "sum");
function SumRecursiveByKey($array,$key)
{
$total = 0;
foreach($array as $_key => $value)
{
if(is_array($value))
{
$total += SumRecursiveByKey($array,$key);
}elseif($_key == $key)
{
$total += $value;
}
}
return $total;
}
use like
$summed_items = SumRecursiveByKey($myArray,'pv');
This would give you more leeway in checking alternative keys a swell.
$sum = 0;
function sumArray($item, $key, &$sum)
{
if ($key == 'pv')
$sum += $item;
}
array_walk_recursive($array, 'sumArray',&$sum);
echo $sum;
$array = array('1000'=> array('pv'=>36), array('1101' => array('pv'=>92)));
$total = 0;
foreach(new recursiveIteratorIterator( new recursiveArrayIterator($array)) as $sub)
{
$total += (int) $sub;
}
print_r($total);
private function calculateUserGv($userId) {
$group = $this->arrayUnder($this->_user_tree, $userId);
global $gv;
$gv = 0;
$gv = $this->gvRecursive($group);
return;
}
private function gvRecursive($group) {
global $gv;
foreach ($group as $key => $val) {
if ($key == 'pv') {
$gv += $group[$key];
}
else {
$this->gvRecursive($val);
}
}
return $gv;
}

Increment Value $k use Array Insert loop

I need to increase the value of the $ k variable every time a record of that loop is inserted in order to insert the array I have with the necessary values. Here I leave a part of the code to see if you can help me.
$k = 0;
foreach ($detalles as $d) {
$num = $d['stock'];
$val = floor($num/$limite);
for($i=0;$i<$limite;$i++) {
$arr[$i] = $val;
}
$arr[0] += $num - array_sum($arr);
$this->transac_detail_temp->save([
'id_trx_header'=> $id,
'producto' => $d['id_producto'],
'cantidad' => $arr[$k]++,
'tipo_transaccion'=> 2]
);
} // foreach detalles
I am not sure about your question but hope this will be you
Replace this code
'cantidad' => $arr[$k]++,
to
'cantidad' => $arr[$k],
and this code in last section
$k++;
so final code will be like this
$k = 0;
foreach ($detalles as $d) {
$k++; //added
//echo $k."<br>"; // if you want to check update value of $k
$num = $d['stock'];
$val = floor($num/$limite);
for($i=0;$i<$limite;$i++) {
$arr[$i] = $val;
}
$arr[0] += $num - array_sum($arr);
$this->transac_detail_temp->save([
'id_trx_header'=> $id,
'producto' => $d['id_producto'],
'cantidad' => $arr[$k], //update
'tipo_transaccion'=> 2]
);
}

Array replace not working

The below is my array, where I need to replace the value of 'battle_health'
$battlepokemon= array();
$i = 1;
while($rows = mysql_fetch_assoc($res))
{
$path = mysql_query(" SELECT * FROM pokemons WHERE pk_id = '".$rows['pkmn_id']."' ");
$pokemon = array(
'opponent_increment' => $i,
'id' => $rows['pkmn_id'],
'battle_poke'=> mysql_result($path,0,"path"),
'battle_level' => $rows['level'],
'battle_health' => $rows['health']
);
$i++;
$battlepokemon[]= $pokemon;
}
The code for replacement is:
$i = 1;
foreach ($battlepokemon as $key => $value)
{
if($value['opponent_increment'] == $opponent_increment)
{
$value['battle_health'] = 0;
echo "Data replaced!";
}
$i++;
}
print_r($battlepokemon);
The code above is working..from start to end.. but the value is not replaced with '0' as the code says!
I think I must have missed something!
You need to transfer the reference, not the values. Add a & to the following sentence
foreach ($battlepokemon as $key => &$value)
^
I tried this just for example
<?php
$arr = array('12', '34');
foreach($arr as $key => &$value){
$value = 0;
}
var_dump($arr);
?>
Hopes it can help you
You can achieve this with for Loop Because unlike foreach loop, it doesn't perform an array copy before transversal:
$arr = array('12', '34');
for($i = 0, $count = count($arr); $i < $count; $i++){
$arr[$i] = 0;
}
var_dump($arr);
Or If you want to do with Foreach only, you need to avoid new copy of array by passing the reference like:
$arr = array('12', '34');
foreach($arr as $key => &$value)
{
$value = 0;
}
var_dump($arr);

PHP: how to do foreach and start from sixth element of collection?

is it possible to start a foreach loop from specific element [sixth element]?
im using this code:
<?php
$num=1;
foreach($temp_row as $key => $value) {
echo $num;
$num++;
}
?>
thanks :)
You can use for example array_slice()
$num = 5; //it will start from sixth element
foreach(array_slice($temp_row, $num) as $key => $value) {
echo $key.'=>'.$value.'<br>';
}
Not directly with a foreach(). The clue is in the each part of the name. It loops through all elements.
So how can we achieve it?
You could always just have an if() clause inside the loop that checks the key value before doing the rest of the work.
But if that's not workable for you, for whatever reason, I'd suggest using a FilterIterator to achieve this.
The FilterIterator is a standard PHP class which you can extend to create your own filters. The iterator can then be looped using a standard foreach() loop, picking up only the records that are accepted by the filter.
There are some examples on the manual page linked above that will help, but here's a quick example I've thrown together for you:
class SkipTopFilter extends FilterIterator {
private $filterNum = 0;
public function __construct(array $array, $filter) {
parent::__construct(new ArrayIterator($array));
$this->filterNum = $filter;
}
public function accept() {
return ($this->getInnerIterator()->key() >= $this->filterNum);
}
}
$myArray = array(13,6,8,3,22,88,12,656,78,188,99);
foreach(new SkipTopFilter($myArray, 6) as $key=>$value) {
//loop through all records except top six.
print "rec: $key => $value<br />";
}
Tested; outputs:
rec: 6 => 12
rec: 7 => 656
rec: 8 => 78
rec: 9 => 188
rec: 10 => 99
you could skip if counter is not 6th element...
<?php
$num=0;
foreach($temp_row as $key => $value) {
if( ++$num < 6 )
{
continue;
}
echo $num;
}
?>
Or with a for loop
$num = 1;
for($i=5; $i<= count($temp_row), $i++) {
echo $num;
$num++;
}
try this code:
$new_temp_row = array_slice($temp_row, 5);
foreach($new_temp_row as $key => $value) {
echo $value;
}
You may create new array with needed data part of origin array and work with it:
$process = array_slice ($temp_row, 5);
foreach($process as $key => $value) {
//TODO Your logic
}
Or you may skipp first siel elments:
<?php
$num=1;
foreach($temp_row as $key => $value) {
if ($num < 6) {
$num++;
continue;
}
//TODO Your logic
}
?>
I suggest you use a for look instead of a for each. You can then access both the key and value that are at i position inside your loop.
<?php
$num = 1;
$keys = array_keys( $temp_row );
for( $i = 5; $i < count( $temp_row ); $i++ ) {
$key = $keys[$i];
$val = $temp_row[$i];
echo $i;
}
?>
$i = 1;
foreach ($temp_row as $key => $value) {
if (($num = $i++) < 6) continue;
// Do something
}
Or
for ($i = 0; $i < 5; $i++) next($temp_row);
while(list($key, $value) = each($temp_row)) {
// Do something
}

get array index based on multiple values

I have an array with about 360 keys:
$threadColours['Apricot'] = array(250,180,160,3341,328,826,194,3332,0);
$threadColours['Apricot, Light'] = array(255,230,225,3824,8,833,2605,-1,1);
$threadColours['Apricot, Medium'] = array(255,135,105,3340,329,827,193,-1,2);
I am retrieving a pixel rgb values that came from this array. So I need to get the key where, for example, $threadColours[???][0]=250, [1]=180, [2]=160. I know you can search for a single key but I cannot figure out how to match multiple values. Just to be clear, I have the rgb values I just want to know how to get the key that has all three values in [0],[1],[2] respectively.
Thank you much,
Todd
function getColourKey($colours, $r, $g, $b) {
foreach ($colours as $key => $value)
if ($value[0] == $r && $value[1] == $g && $value[2] == $b)
return $key;
return NULL;
}
You can use code like this:
$threadColours['Apricot'] = array(250,180,160,3341,328,826,194,3332,0);
$threadColours['Apricot, Light'] = array(255,230,225,3824,8,833,2605,-1,1);
$threadColours['Apricot, Medium'] = array(255,135,105,3340,329,827,193,-1,2);
$needle=array(2605,-1,1); // this is your r,g,b
$startIndex = -1;
$rootElem = "";
foreach ($threadColours as $key => $arr) {
for ($i=0; $i < count($arr); $i+=3) {
if ( $arr[$i] == $needle[0] &&
$arr[$i+1] == $needle[1] &&
$arr[$i+2] == $needle[2]
) {
$rootElem = $key;
$startIndex = $i;
break;
}
}
}
printf("rootElem=[%s], startIndex=[%s]\n", $rootElem, $startIndex);
OUTPUT:
rootElem=[Apricot, Light], startIndex=[6]
$search = array(250, 180, 160);
$color = null;
foreach ($threadColours as $key => $val) {
if (array_slice($val, 0, 3) == $search) {
$color = $key;
break;
};
}

Categories