Replacing array value in foreach loop - php

What am I doing wrong here? It's so simple and I'm overlooking something. I'm trying to replace the value of an array key within a foreach loop:
$arr = array();
$arr['firstimg'] = '123';
$arr['secondimg'] = '456';
$arr['thirdimg'] = '789';
foreach ($arr as $key => $value) {
if ($key == 'secondimg') {
$value = '000';
}
}
print_r($arr);
The array is staying the same.

The variable $value is scoped to the loop. You need to update the value of $arr[$key].
Alternatively you can declare the loop as follows:
foreach ($arr as $key => &$value) {
This makes $value a reference to the original array value (rather than a copy).

Should Be :
foreach ($arr as $key => $value) {
if ($key == 'secondimg') {
$arr['secondimg'] = '000';
}
}

pass by refrence,
$arr = array();
$arr['firstimg'] = '123';
$arr['secondimg'] = '456';
$arr['thirdimg'] = '789';
foreach ($arr as $key => $value) {
if ($key == 'secondimg') {
$value = '000';
}
}
print_r($arr);
to
$arr = array();
$arr['firstimg'] = '123';
$arr['secondimg'] = '456';
$arr['thirdimg'] = '789';
foreach ($arr as $key => &$value) {
if ($key == 'secondimg') {
$value = '000';
}
}
print_r($arr);

Related

PHP How to merge array element with next while maintaining order?

$array = ['coke.','fanta.','chocolate.'];
foreach ($array as $key => $value) {
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
} else {
$new[] = $value;
}
}
This code doesn't have the desired effect, in fact it doesn't work at all. What I want to do is if an array element has string length less than 5, join it with the next element. So in this case the array should turn into this:
$array = ['coke. fanta.','chocolate.'];
$array = ['coke.','fanta.','chocolate.', 'candy'];
$new = [];
reset($array); // ensure internal pointer is at start
do{
$val = current($array); // capture current value
if(strlen($val)>=6):
$new[] = $val; // long string; add to $new
// short string. Concatenate with next value
// (note this moves array pointer forward)
else:
$nextVal = next($array) ? : '';
$new[] = trim($val . ' ' . $nextVal);
endif;
}while(next($array));
print_r($new); // what you want
Live demo
With array_reduce:
$array = ['coke.', 'fanta.', 'chocolate.', 'a.', 'b.', 'c.', 'd.'];
$result = array_reduce($array, function($c, $i) {
if ( strlen(end($c)) < 6 )
$c[key($c)] .= empty(current($c)) ? $i : " $i";
else
$c[] = $i;
return $c;
}, ['']);
print_r($result);
demo
<pre>
$array = ['coke.','fanta.','chocolate.'];
print_r($array);
echo "<pre>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
</pre>
Updated Code after adding pop after chocolate.
<pre>
$array = ['coke.','fanta.','chocolate.','pop'];
print_r($array);
echo "<br>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6 && !empty($array[$key+1])) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
<pre>
You need to skip the iteration for the values that you have already added.
$array = ['coke.', 'fanta.', 'chocolate.'];
$cont = false;
foreach ($array as $key => $value) {
if ($cont) {
$cont = false;
continue;
}
if (strlen($value) < 6 && isset($array[$key+1])) {
$new[] = $value.' '.$array[$key+1];
$cont = true;
}
else {
$new[] = $value;
}
}
print_r($new);

how to use variable outside foreach loop

How to return $value after loop with its returned data ? I think to create array before loop and equal it to $v to use it after loop but it didn't work.
Any idea on how to solve this problem ?
// create array
$v = array();
// start loop
foreach ($this->json_data->locations as $key => $value) {
if ($value->country_name == $data['city']->country_name)
// return $value with data
return $v = $value ;
}
echo $v->country_name
try this:
$v = array();
foreach ($this->json_data->locations as $key => $value) {
if ($value->country_name == $data['city']->country_name)
{
if(!in_array($value,$v))
{
array_push($v,$value);
}
}
}
try this
$v = array();
$i=0;
// start loop
foreach ($this->json_data->locations as $key => $value) {
if ($value->country_name == $data['city']->country_name)
// return $value with data
$i++;
$v[$i] = $value ;
}
//print $v
print_r($v)
If like using 'return' try this.
$v = iLikeUsingReturn($this,$data);
function iLikeUsingReturn($t,$d){
foreach ($t->json_data->locations as $key => $value) {
if ($value->country_name == $d['city']->country_name)
return $value ;
}
return array();
}
I think the following code will helps you.
// create array
$v = array();
// start loop
foreach ($this->json_data->locations as $key => $value) {
if ($value->country_name == $data['city']->country_name)
// return $value with data
array_push($v, $value);
}
return $v;

PHP set dynamic array index

I have the following key/value from my $_POST variable:
Array
(
'translations_0_comment' => 'Greetings from UK'
)
What I would like is to set this values to the following array
$data[translations][0][comment] = 'Greetings from UK';
So the idea is that I can have anything in my KEY values, and from that I will populate an array.
Is there any safe way to do this without using eval() ?
All help is appreciated.
UPDATE:
this would be the idea with eval()
foreach ($_POST as $key => $dataValue) {
$a = explode("_", $key);
$builder = '$object';
foreach ($a as $value) {
$builder.='['.$value.']';
}
$builder.=' = '.$dataValue.';';
eval($builder);
}
I think you are looking for this
function set_value($object, $paths, $value, $index){
$key = $paths[$index];
$sub_object = $object[$key];
if (!is_array($sub_object)){
$object[$key] = $value;
}else{
$index = $index+1;
$object[$key] = set_value($sub_object, $paths, $value, $index);
}
return $object;
}
explode() is what you need:
$data = array();
foreach ($postData as $key => $val) {
$explodedKey = explode('_', $key);
$data[$explodedKey[0]][$explodedKey[1]][explodedKey[2]] = $val;
}
No need to use eval().
I think this is what you are looking for
Example
In your form which generate the $_POST data rename the input attribute as follows
<input name="data[translations][0][comment]" />
and now your $_POST['data'] will be an array
$data = array();
foreach ($_POST as $keys => $val) {
$keys_list = explode('_', $keys);
$link = &$data;
foreach ($keys_list as $key) {
$link[$key] = $val;
$link = &$link[$key];
}
}
Try this one sir.
$array = array
(
'TRY_THIS_ONE_SIR_PLEASE_THANKS' => 'Greetings from UK'
);
$array1 = array_keys($array);
$arrValue = array_values($array);
$array1 = explode("_", $array1[0]);
$ctr = count($array1);
for($i=0; $i<$ctr; $i++)
{
$start .= "array(\"".$array1[$i]."\" => ";
$end .=")";
}
$start = $start ."\"".$arrValue[0]."\"".$end;
eval("\$arr = $start;");
print_r($arr);

How to check for duplicates in an array and then do something with their values in PHP?

I have an array for example ("1:2","5:90","7:12",1:70,"29:60") Wherein ID and Qty are separated by a ':' (colon), what I want to do is when there's a duplicate of IDs the program will add the qty and return the new set of arrays so in the example it will become ("1:72","5:90","7:12","29:60").
Ex.2
("1:2","5:90","7:12","1:70","29:60","1:5")
becomes
("1:77","5:90","7:12","29:60").
<?php
$arr = array("1:2","5:90","7:12", "1:70","29:60");
$newArr = array();
foreach($arr as $key => $value) {
list($id, $quantity) = explode(':', $value);
if(isset($newArr[$id]))
$newArr[$id] += $quantity;
else
$newArr[$id] = $quantity;
}
foreach($newArr as $key => $value) {
$newArr[$key] = "$key:$value";
}
print_r($newArr);
Simple step by step:
$arr = array("1:2","5:90","7:12","1:70","29:60");
$tmp = array();
foreach($arr as $item)
{
list($id, $value) = explode(':', $item);
if (isset($tmp[$id]))
$tmp[$id] += $value;
else
$tmp[$id] = $value;
}
$arr = array();
foreach($tmp as $id => $value)
array_push($arr, $id . ':' . $value);
var_dump($arr);
Assuming the data format is an actual array, or you can parse it into one:
$data = array("1:2","5:90","7:12","1:70","29:60","1:5");
$values = array();
foreach ($data as $value) {
list($id, $qty) = explode(':', $value);
if (isset($values[$id])) {
$values[$id] += $qty;
} else {
$values[$id] = $qty;
}
}
foreach ($values as $id => &$qty) {
$qty = "$id:$qty";
}
$values = array_values($values);
Try to do like this
$array = array("1:2","5:90","7:12","1:70","29:60","1:5");
$result = array();
$sum = array();
foreach($array as $value)
{
list($k,$v) = explode(':',$value);
$sum[$k] += $v;
$result[$k] = $k.':'.$sum[$k];
}
unset($sum);
print_r($result);

How to get values in an array this way with PHP?

From:
$arr = array(array('key1'=>'A',...),array('key1'=>'B',...));
to:
array('A','B',..);
$output = array();
foreach ($arr as $array_piece) {
$output = array_merge($output, $array_piece);
}
return array_values($output);
On the other hand, if you want the first value from each array, what you want is...
$output = array();
foreach ($arr as $array_piece) {
$output[] = array_unshift($array_piece);
}
But I'm thinking you want the first one.
Relatively simple conversion by looping:
$newArray = array()
foreach ($arr as $a) {
foreach ($a as $key => $value) {
$newArray[] = $value;
}
}
Or, perhaps more elegantly:
function flatten($concatenation, $subArray) {
return array_merge($concatenation, array_values($subArray));
}
$newArray = array_reduce($arr, "flatten", array());
John's solution is also nice.
Something like this should work
<?
$arr = array(array('key1'=>'A','key2'=>'B'),array('key1'=>'C','key2'=>'D'));
$new_array = array();
foreach ($arr as $key => $value) {
$new_array = array_merge($new_array, array_values($value));
}
var_export($new_array);
?>
If you want all the values in each array inside your main array.
function collapse($input) {
$buf = array();
if(is_array($input)) {
foreach($input as $i) $buf = array_merge($buf, collapse($i));
}
else $buf[] = $input;
return $buf;
}
Above is a modified unsplat function, which could also be used:
function unsplat($input, $delim="\t") {
$buf = array();
if(is_array($input)) {
foreach($input as $i) $buf[] = unsplat($i, $delim);
}
else $buf[] = $input;
return implode($delim, $buf);
}
$newarray = explode("\0", unsplat($oldarray, "\0"));

Categories