I am adding other value array inside foreach loop which working fine for me.
$i = true;
$array = array('red', 'blue');
foreach($array as $key => & $value) {
echo $value . '<br />';
if ($i === true) {
$others = array('white', 'yellow');
foreach($others as $key => & $other_value) {
$array[] = $other_value;
}
}
$i = false;
}
Output
red
blue
white
yellow
but i want to reshuffle array value inside foreach loop need output like below
red
white
yellow
blue
You won't be able to do it on $array without some serious array_slice()ing. So, just assign to another array $result and you will get the $other array inserted between the first and second elements of $array:
$i = true;
$array = array('red', 'blue');
foreach($array as $value) {
$result[] = $value; // here...
if ($i === true) {
$others = array('white', 'yellow');
foreach($others as $other_value) {
$result[] = $other_value; // and here...
}
}
$i = false;
}
If needed (for whatever reason) $array = $result;
A cool solution would be like this:
$array = array('red', 'blue');
$others = array('white', 'yellow');
$temp = array_combine($array,$others);
$final = array();
foreach($temp as $key => $value) {
array_push($final,$key,$value);
}
$array = $final;
$i = true;
$array = array('red', 'blue');
foreach($array as $key => & $value) {
echo $value . '<br />';
if ($i === true) {
$a1= $array;
$a2= array($value);
$result=array_diff($a1,$a2);
$others = array('white', 'yellow');
$array = array_merge($others,$result);
}
$i = false;
}
see output
Related
I have an array that looks like this:
$ratingsInPosts = array
(
array("1",3),
array("2",5),
array("2",2),
array("5",2),
array("90",1),
array("5",6),
array("2",2),
);
I Want to find duplicate values in the first column and avarage its values from the second column.
So that this("1",3),("2",5),("2",2),("5",2),("90",1),("5",6),("2",2)
ends up like this ("1",3),("2",3),("5",4),("90",1)
Try this tested solution
I got the required Output
$ratingsInPosts = array
(
array("1",3),
array("2",5),
array("2",2),
array("5",2),
array("90",1),
array("5",6),
array("2",2),
);
$arr1 = array_column($ratingsInPosts, 0);
$p = array_count_values($arr1);
foreach($p as $key => $value)
{
$sum = 0;
for($i=0; $i < $value; $i++)
{
$pos = array_search($key, $arr1);
$sum += $ratingsInPosts[$pos][1];
unset($arr1[$pos]);
unset($ratingsInPosts[$pos]);
}
$re[] = array('"'.$key.'"',$sum/$value);
}
print_r($re);
I hope it helps you:
$groups = array();
// in this loop we group values by first column
foreach ($ratingsInPosts as $row) {
$key = $row[0];
if (!isset($groups[$key]) {
$groups[$key] = array();
}
$groups[$key][] = $row[1];
}
$result = array();
foreach ($groups as $key => $value) {
$avg = array_sum($value) / count($value);
$row = array($key, $avg);
$result[] = $row;
}
<?php
header('Content-Type: text/plain');
$ratingsInPosts = array(array("1",3),array("2",5),array("2",2),array("5",2),array("90",1),array("5",6),array("2",2));
$result = array();
$output = array();
foreach($ratingsInPosts as $array){
$result[$array[0]][] = $array[1];
}
foreach($result as $key=>$array){
$output[] = array($key,round(array_sum($array)/count($array)));
}
var_export($output);
?>
$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);
I have an array like that
$products = array(array(354),array(1),array(375),array(1),array(344),array(2));
and i want to achieve array like that
$arrProducts= array(array('product_id'=>354,'qty'=>1),array('product_id'=>375,'qty'=>1),array('product_id'=>344,'qty'=>2));
I achieved this array using this code
foreach($products as $val)
{
$abc[] =$val[0];
}
for($i=0;$i<count($abc);$i++)
{
if($i%2==0)
{
$newarr[]['product_id'] = $abc[$i];
}
else{
$newarr[]['qty'] = $abc[$i];
}
}
for($j=0;$j<count($newarr);$j++)
{
if($j%2==0)
{
$arrProducts[] = array_merge($newarr[$j],$newarr[$j+1]);
}
else{
continue;
}
}
echo '<pre>';
print_r($arrProducts);
but i think my way to get this array is too long so how can i get this array in short way using some array functions or should i use this code?
You can use array_chunk in this case if this is always by twos, and combine it with array_combine():
$products = array(array(354),array(1),array(375),array(1),array(344),array(2));
$products = array_chunk($products, 2);
$arrProducts = array();
$keys = array('product_id', 'qty');
foreach($products as $val) {
$arrProducts[] = array_combine($keys, array(reset($val[0]), reset($val[1])));
}
echo '<pre>';
print_r($arrProducts);
Another alternative would be:
$products = array(array(354),array(1),array(375),array(1),array(344),array(2));
$keys = array('product_id', 'qty');
$arrProducts = array_map(function($e) use ($keys) {
return array_combine($keys, array_map('reset', $e));
}, array_chunk($products, 2));
This will yield the same result.
Consume two array elements on each iteration:
$arrProducts = array();
$inputLength = count($products);
for ($i = 0; $i < $inputLength; $i += 2) {
$arrProducts[] = array('product_id' => $products[$i][0], 'qty' => $products[$i+1][0]);
}
$i=1;
$j=0;
foreach($products as $val)
{
if(($i%2) == 0)
{
$abc[$j]['qty'] =$val[0];
$j++;
}
else
{
$abc[$j]['product_id'] =$val[0];
}
$i++;
}
I have array like this:
$array1 = array(Array('a','d'),
Array('c','a'),
Array('d','a'),
Array('a','b','c','d','e'),
);
$array2 = array(array('a','d'), array('a','b','c','d','e')) ;
$result = array();
Here's my code:
foreach ($array2 as $part) {
$key = implode(', ', $part);
if( ! array_key_exists ($key, $array1)) {
$result[$key] = 0;
}
$result[$key] = $result[$key] + 1;
}
foreach ($result as $key => $value) {
echo "$value of {$key}<br/>";
}
I want to count values $array2 based on $array1
I got this one:
1 of a,d
1 of a,b,c,d,e
But I want a result like this:
3 of a,d
1 of a,b,c,d,e
If anybody wonders why there's (3 of a,d), it count from array('a','d'), array('d','a') also counted as array('a','d') and array('a','b','c','d','e')
Try this. Here is a working demo https://eval.in/117810
<?
$array1 = array(array('a','d'),
array('c','a'),
array('d','a'),
array('a','b','c','d','e'),
);
$array2 = array(array('a','d'), array('a','b','c','d','e')) ;
$result = array();
foreach ($array2 as $key=>$part2) {
sort($part2);
if(!isset($result[$key]))$result[$key]=0;
foreach($array1 as $part1) {
$intersect = array_intersect($part1, $part2);
sort($intersect);
if ($intersect === $part2) {
$result[$key]++;
}
}
}
foreach($result as $k=>$v) {
echo $v . " of " . implode(',', $array2[$k]) . "<br/>";
}
?>
Whats the easiest way to invert a multidimensional array. By invert I mean similar to array_flip.
e.g
[0][5][var_name] = data
[0][3][var_name2] = data2
[1][var_name3] = data3
[0][1][4][var_name4] = data4
inverted would be:
[var_name][0][5] = data
[var_name2][0][3] = data2
[var_name3][1] = data3
[var_name4][0][1][4] = data4
Any ideas?
You could store a list of the keys of all ancestors and when you hit a "leaf" use this list to create the "flipped" version.
<?php
$data = array(
0=>array(
5=>array('var_name' => 'data'),
3=>array('var_name2' => 'data2'),
1=>array(4=>array('var_name4'=>'data4'))
),
1=>array('var_name3'=>'data3')
);
$result = array();
foo($data, $result);
($result['var_name'][0][5] === 'data') or die('1');
($result['var_name2'][0][3] === 'data2') or die('2');
($result['var_name3'][1] === 'data3') or die('3');
($result['var_name4'][0][1][4] === 'data4') or die('4');
echo 'ok';
function foo(array $a, array &$target, $stack=array()) {
foreach($a as $key=>$value) {
if ( is_array($value) ) {
array_push($stack, $key);
foo($value, $target, $stack);
array_pop($stack);
}
else {
$target[$key] = array();
$tmp = &$target[$key];
foreach( $stack as $s ) { // now it's not so stack-ish anymore :-S
$tmp[$s] = array();
$tmp = &$tmp[$s];
}
$tmp = $value;
}
}
}
I couldn't think of an easy way to do this. So I wrote up a really complicated way to do it. Namely:
Take the multidimensional array and flatten it into a list of keys and values.
Reverse the keys.
Unflatten the list to obtain an inverted multidimensional array.
Code
<?php
function print_entries($array, $prekeys = array())
{
foreach ($array as $key => $value)
{
$keys = array_merge($prekeys, array($key));
if (is_array($value))
print_entries($value, $keys);
else
echo '[' . implode('][', $keys) . "] = $value\n";
}
}
function flatten_array($array)
{
$entries = array();
foreach ($array as $key => $value)
{
if (is_array($value))
{
foreach (flatten_array($value) as $subentry)
{
$subkeys = $subentry[0];
$subvalue = $subentry[1];
$entries[] = array(array_merge(array($key), $subkeys), $subvalue);
}
}
else
$entries[] = array(array($key), $value);
}
return $entries;
}
function unflatten_array($entries)
{
$array = array();
foreach ($entries as $entry)
{
$keys = $entry[0];
$value = $entry[1];
$subarray = &$array;
foreach ($keys as $i => $key)
{
if ($i < count($keys) - 1)
{
if (!isset($subarray[$key]))
$subarray[$key] = array();
$subarray = &$subarray[$key];
}
else
$subarray[$key] = $value;
}
}
return $array;
}
function invert_array($array)
{
$entries = flatten_array($array);
foreach ($entries as &$entry)
$entry[0] = array_reverse($entry[0]);
return unflatten_array($entries);
}
$array = array
(
0 => array
(
5 => array('var_name' => 'data'),
3 => array('var_name2' => 'data2'),
1 => array(4 => array('var_name4' => 'data4'))
),
1 => array(0 => array('var_name' => 'data3'))
);
print_entries($array);
echo "\n";
print_entries(invert_array($array));
?>
Output
[0][5][var_name] = data
[0][3][var_name2] = data2
[0][1][4][var_name4] = data4
[1][0][var_name] = data3
[var_name][5][0] = data
[var_name2][3][0] = data2
[var_name4][4][1][0] = data4
[var_name][0][1] = data3
Edit: I noticed now that you don't reverse the keys but you simply move the var_name portion from the end to the front and leave the numerical indices alone. It's easy enough to modify the line in flatten_array where I call array_reverse to re-order the keys in a different way. The core flatten/unflatten logic would not need to be changed. I leave this as an exercise for the reader. :-)