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]
);
}
Related
How can I add one element of array with every element of another array using foreach loop in php?
For clear understanding attaching screen shot.
in this picture element at index one will be add to all elements of another array. then element at index two will be add to every element of another array and so on...
Please review below code.
<?php
$arr = array(11,12,13,14,15);
$arrAnotherArray = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$subArrLen = count($arrAnotherArray);
foreach($arr as $key => $value){
$arr[$key] = array();
$sum = 0;
foreach($arrAnotherArray as $key1=>$val){
$sum = $value + $val;
array_push($arr[$key],$sum);
}
}
echo "<pre>";
print_r($arr);
echo "</pre>";
?>
Try Like this :
$mainArray = array("11","12","13"....);
$returnArray = array();
foreach($mainArray as $key => $value){
$subArray = array();
//Create the sub array here as you want it.
$subArray[] = $key + 1;
$subArray[] = $key + 2;
$subArray[] = $key + 3;
$subArray[] = $key + 4;
$subArray[] = $key + 5;
$subArray[] = $key + 6;
$returnArray[$value] = $subArray;
}
I don't understand how you want your output to be formatted but here's the addition logic...
$main = range(11,14);
$sub = range(1,6);
$output = [];
foreach ($main as $mainNumber) {
foreach ($sub as $subNumber) {
$output[$mainNumber . '+' . $subNumber] = $mainNumber + $subNumber;
}
}
var_dump($output);
In my code I have two elements which has the same age "Joe"=>"43" and "Rob"=>"43" .
My code output is:
Joe
I want to output:
Joe and Rob
Because they has the highest value.
This is my code:
<?php
$cur = 1;
$age = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$new_array = array();
arsort($age);
$new_array = $age;
$key = array_search(max($new_array), $new_array);
while ($cur > 0) {
echo $key;
$cur--;
}
?>
I'd change the keys and values in the array, then sort by key and return the values of the first key:
$ages = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$new = array();
foreach ($ages as $name => $age) {
$new[$age][] = $name;
}
uksort($new, function($ka, $kb) { return $kb - $ka; }); // or just krsort($new);
$new = array_values($new)[0]; // <- to use this you have to have at least PHP 5.4
// if you have PHP < 5.4 you can simply do it in two steps:
// $new = array_values($new);
// $new = $new[0];
See it in action!
EDIT: even simpler!
$ages = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$max = max($ages);
$new = array_keys(array_filter($ages, function ($age) use ($max) { return $age == $max; }));
Use:
$people = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$max = max($people);
$result = array_filter($people, function($age) use ($max){ return $max == $age; });
The result is:
Array
(
[Joe] => 43
[Rob] => 43
)
Just check it manually:
$age = array("Peter" => "35", "Ben" => "37", "Joe" => "43", "Rob" => "43");
$new_array = array();
arsort($age);
$new_array = $age;
$max = max($new_array);
$results = array();
foreach ($new_array as $key => $val) {
if ($val == $max) {
$results[] = $key;
}
}
echo implode(' and ', $results);
// will output "joe and bob"
I like the answer of #matteo-tassinari and #evilive much more and wanted to propose it myself. But since the question of efficency came up, here is a solution using only one loop and therefore has a linear time complexity:
<?php
$max = ~PHP_INT_MAX;
$result = [];
foreach($age as $key => $value) {
if($value > $max) {
$result = [ $key => $value ];
$max = $value;
}
if($value == $max) {
$result[$key] = $value;
}
}
var_dump($result);
And there exists another solution, that uses bucket sort:
function bucket($ages) {
$buckets = [];
foreach($ages as $key => $value) {
$buckets[$value][] = $key;
}
return $buckets[max(array_keys($buckets))];
}
Regarding the discusson about peformance and scalability, I wrote a small benchmark script for four kinds of proposed solutions (loop, sort, filter, bucket):
<?php
function loop($ages) {
$max = 0;
$result = [];
foreach($ages as $key => $value) {
if($value > $max) {
$result = [ $key => $value ];
$max = $value;
}
if($value == $max) {
$result[$key] = $value;
}
}
return array_keys($result);
}
function filter($ages) {
$max = max($ages);
$new = array_filter($ages, function ($age) use ($max) { return $age == $max; });
return array_keys($new);
}
function bucket($ages) {
$buckets = [];
foreach($ages as $key => $value) {
$buckets[$value][] = $key;
}
return $buckets[max(array_keys($buckets))];
}
for($n = 2; $n < 10000000; $n*=2) {
$ages = [];
for($i = 0; $i < $n; $i++) {
$ages['name_'.$i] = rand(0,100);
}
$start = microtime(true);
echo $n.';';
loop($ages);
echo (microtime(true) - $start).';';
$start = microtime(true);
arsort($ages);
echo (microtime(true) - $start).';';
$start = microtime(true);
filter($ages);
echo (microtime(true) - $start).';';
bucket($ages);
echo (microtime(true) - $start).';';
echo PHP_EOL;
}
Limited Live Test
Please double-check if this is right: Using php-5.6.15 on the command line, my timings look something like this:
elements;loop;sort;filter;bucket
...
4096;0.001507;0.009868;0.01211;0.01453;
8192;0.003704;0.002483;0.02488;0.03035;
16384;0.006660;0.01010;0.05396;0.06723;
32768;0.01417;0.01271;0.09163;0.1163;
...
1048576;0.4227;0.9791;2.983;3.943;
2097152;0.8572;2.320;6.064;8.020;
4194304;1.787;4.981;11.90;16.04;
8388608;3.892;10.84;24.76;33.31;
For small number of elements, the difference between the methods is not really big, but as you can see, for the largest value the loop method is two times faster than sort, 8 times faster than filter and eleven times faster than bucket. So if your array is huge, you should use loop.
I'd do something like this
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43");
$max = max($age); //get the highest age
foreach ($age as $key => $value) { //iterate through $age array
if ($value == $max) { //if the value is equal to max age
echo $key."<br />"; // then echo the key
}
}
You can use the array methods next and key.
With next() you will move the array pointer one position. With key() you will get the key of the element of the array pointer. So the final code will be something like this:
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43");
arsort($age);
echo key($age);
next($age);
echo key($age);
Check it working here.
I'm wondering why no one is using built in solution:
$age = array("Peter"=>"35","Ben"=>"37","Joe"=>"43","Rob"=>"43");
$new = array_keys($age, max($age));
returns
array('Joe', 'Rob')
https://www.php.net/manual/en/function.array-keys.php says:
array_keys ( array $array , mixed $search_value [, bool $strict = FALSE ] ) : array
If a search_value is specified, then only the keys for that value are returned. Otherwise, all the keys from the array are returned.
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);
As the title states I'm searching for a unique solution in multi arrays. PHP is not my world so I can't make up a good and fast solution.
I basically get this from the database: http://pastebin.com/vYhFCuYw .
I want to check on the 'id' key, and if the array contains a duplicate 'id', then the 'aantal' should be added to each other.
So basically the output has to be this: http://pastebin.com/0TXRrwLs .
Thanks in advance!
EDIT
As asked, attempt 1 out of many:
function checkDuplicates($array) {
$temp = array();
foreach($array as $k) {
foreach ($array as $v) {
$t_id = $k['id'];
$t_naam = $k['naam'];
$t_percentage = $k['percentage'];
$t_aantal = $k['aantal'];
if ($k['id'] == $v['id']) {
$t_aantal += $k['aantal'];
array_push($temp, array(
'id' => $t_id,
'naam' => $t_naam,
'percentage' => $t_percentage,
'aantal' => $t_aantal,
)
);
}
}
}
return $temp;
}
How about this code, each 'aantal' has initial value of 1, and duplicated id have their aantal incremented mutually, and duplicated id's are not suppressed. As your first array index is 0-based numeric, so we don't consider this dimension as a hash array, but rather a normal array.
UPDATED: id's can be duplicated 2 times, 3 times, 4 times, ...
<?php
//
// duplicate elements are not suppressed:
//
function checkDuplicates($xarr) {
//
$xarrDone = array();
//
$n = count($xarr);
//
for($i = 0; $i < $n; $i++)
{
if(! isset($xarrDone[$i]))
{
$id0 = $xarr[$i]['id'];
$hasId0 = array();
for($j = $i + 1; $j < $n; $j++)
{
if($xarr[$j]['id'] == $id0)
{
$hasId0[] = $j;
}
}
$n1 = count($hasId0);
if($n1 > 0)
{
$xarr[$i]['aantal'] += $n1;
$xarrDone[$i] = true;
for($j = 0; $j < $n1; $j++)
{
$xarr[$hasId0[$j]]['aantal'] += $n1;
$xarrDone[$hasId0[$j]] = true;
}
}
}
}
//
return $xarr;
}
//
// duplicate elements are suppressed:
//
function checkDuplicates2Unique($xarr) {
//
$xarrDone = array();
$xarrNew = array();
//
$n = count($xarr);
//
for($i = 0; $i < $n; $i++)
{
if(! isset($xarrDone[$i]))
{
$id0 = $xarr[$i]['id'];
$hasId0 = array();
for($j = $i + 1; $j < $n; $j++)
{
if($xarr[$j]['id'] == $id0)
{
$hasId0[] = $j;
}
}
$n1 = count($hasId0);
if($n1 > 0)
{
$xarr[$i]['aantal'] += $n1;
for($j = 0; $j < $n1; $j++)
{
$xarrDone[$hasId0[$j]] = true;
}
}
$xarrNew[] = $xarr[$i];
$xarrDone[$i] = true;
}
}
//
return $xarrNew;
}
//
// main test:
//
$xarr0 = array(
array(
'id' => 6
, 'naam' => 'Aardmonnik'
, 'percentage' => '8,00%'
, 'aantal' => 1
)
, array(
'id' => 34
, 'naam' => 'Achel 8 Bruin'
, 'percentage' => '8,00%'
, 'aantal' => 1
)
, array(
'id' => 34
, 'naam' => 'Achel ppBruin'
, 'percentage' => '9,00%'
, 'aantal' => 1
)
, array(
'id' => 34
, 'naam' => 'Achel ppBruin'
, 'percentage' => '9,00%'
, 'aantal' => 1
)
, array(
'id' => 3
, 'naam' => 'IV Saison'
, 'percentage' => '6,5%'
, 'aantal' => 1
)
, array(
'id' => 34
, 'naam' => '3 Schténg'
, 'percentage' => '6,00%'
, 'aantal' => 1
)
);
//
echo "<pre>
Original:
";
print_r($xarr0);
//
echo "</pre>";
//
$xarr = checkDuplicates($xarr0);
//
echo "<pre>
Modified:
";
print_r($xarr);
//
$xarr = checkDuplicates2Unique($xarr0);
//
echo "<pre>
Modified Unique:
";
print_r($xarr);
//
echo "</pre>";
?>
?
checkDuplicates(): keep duplicated id's.
checkDuplicates2Unique(): delete duplicated id's to get unique id's.
Try using php's array_unique function: http://php.net/manual/en/function.array-unique.php
It should work on arrays
Otherwise (if you can sort the array -> faster):
<?php
$db = array(....); // your data
function remove_duplicates (array $arr) {
usort($arr, function ($a, $b) {
return $a['id'] < $b['id'];
});
$result = array();
$last_id = null;
$last_index = -1;
for ($i=0; $i<count($arr); ++$i) {
if ($arr[$i]['id'] == $last_id) {
result[$last_index]['aantai'] += 1;
continue;
}
$last_id = $arr[$i]['id'];
$last_index = count($result);
$result[] = $arr[$i];
}
return $result;
}
?>
Only loop over the input once, then copy the element when the id is new, else add the value:
function checkDuplicates($array) {
$temp = array();
// Only loop through the input once
foreach($array as $k) {
// Use the id as array index
if (array_key_exists($k['id'], $temp) {
// Only check id and add aantal?
$temp[$k['id']['aantal'] += $k['aantal'];
} else {
// Copy the element to the output
$temp[$k['id']] = $k;
}
}
return $temp;
}
Depending on your further code, you might need to reset the array indices by sort() or something.
Edit: sorry I forgot an index to $temp - the aantal field schould be correct now.
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
}