How to shuffle list in PHP - php

I have been looking through stackoverflow, and I found nothing that answered my question, on how I shuffle a list without getting the associative arrays. Since my code uses shuffle_assocI get the associative arrays, but using shuffle didn't get me anywhere, so now I turn here.
function shuffle_assoc($list) {
if (!is_array($list)) return $list;
$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach ($keys as $key) {
$random[] = $list[$key];
}
return $random;
}
$arr = array();
$arr[] = "test 1<br>";
$arr[] = "test 2 <br>";
$arr[] = "test 3 <br>";
$arr[] = "test 4 <br>";
print_r(shuffle_assoc($arr));
?>
This is how it looks when I run the code
However I don't want the Array ([0] => parts to show, I only want to randomly shuffle the test(1/2/3/4)list every time I run the code.

print_r function display data as they are. So it print array when you give it array. You need to implode your array into string:
echo implode('',shuffle_assoc($arr));
edit:
or just
echo implode('',shuffle($arr));

Try this:
$array = shuffle($arr);
foreach($array as $a)
{
echo $a;
}

Related

how to get value of key in php associative array by comparing key with a string to get value?

I have below small PHP script, I just need the value from the array if I provide key in $str.
$empid_array = array('CIP004 - Rinku Yadav', 'CIP005 - Shubham Sehgal');
$key = array();
$value = array();
$str = "CIP004";
foreach($empid_array as $code){
$str = preg_split("/\-/", $code);
array_push($key, $str[0]);
array_push($value, $str[1]);
}
$combined = array_combine($key, $value);
echo count($combined);
foreach($combined as $k => $v){
if($str == $k){
echo $v;
}
}
You could simplify your code considerably here. Step one, use array_walk to walk through the array and build the $combined array. Step two, there's no point in looping through the array, just access the value by the index:
$empid_array = ['CIP004 - Rinku Yadav', 'CIP005 - Shubham Sehgal'];
$str = "CIP004";
$combined = [];
// passing $combined by reference so we can modify it
array_walk($empid_array, function ($e) use (&$combined) {
list($id, $name) = explode(" - ", $e);
$combined[$id] = $name;
});
echo $combined[$str] ?? "Not found";

Dynamically generating foreach

I'm trying to write a function that do the following :
Let's say i have an array :
$data = array(
array('10','15','20','25'),
array('Blue','Red','Green'),
array('XL','XS')
)
and my result array should be like :
$result = array(
array('10','15','20','25'),
array('Blue','Red','Green','Blue','Red','Green','Blue','Red','Green','Blue','Red','Green')
array('XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS')
)
Im stuck with this because i want a function that is able to do this no matter how much array there is in the first array $data
I have only been able to write this, which is what give the $result array :
foreach($data[2] as $value2){
$result[2][] = $value2;
foreach($data[1] as $value1){
$result[1][] = $value1;
foreach($data[0] as $value0){
$result[0][] = $value0;
}
}
}
After a few research, it seems that a recursive function is the way to go in order to dynamically generate those foreach but i can't get it to work.
Thanks for your help.
This is dynamic:
$result[] = array_shift($data);
foreach($data as $value) {
$result[] = call_user_func_array('array_merge',
array_fill(0, count($result[0]), $value));
}
Get and remove the first element from original
Loop remaining elements and fill result with values X number of values in first element
Since the elements were arrays merge them all into result
If modifying the original is unwanted, then use this method:
$result[] = reset($data);
while($value = next($data)) {
$result[] = call_user_func_array('array_merge',
array_fill(0, count($result[0]), $value));
}
just use array_fill and array_merge functions
$result = array(
$data[0],
array_merge(...array_fill(0,count($data[0]), $data[1])),
array_merge(...array_fill(0,count($data[0])*count($data[0]), $data[2]))
);
print_r($result);
demo on eval.in

Increasing array elements while in foreach loop in php? [duplicate]

This question already has answers here:
How does PHP 'foreach' actually work?
(7 answers)
Closed 8 years ago.
Consider the code below:
<?php
$arr = array();
$arr['b'] = 'book';
foreach($arr as $key=>$val) {
print "key=>$key\n";
if(!isset($arr['a']))
$arr['a'] = 'apple';
}
?>
It is not displaying 'a'. How foreach works with hash-table(array), to traverse each element. If lists are implement why can't I add more at run time ?
Please don't tell me that I could do this task with numeric based index with help of counting.
Foreach copies structure of array before looping(read more), so you cannot change structure of array and wait for new elements inside loop. You could use while instead of foreach.
$arr = array();
$arr['b'] = 'book';
reset($arr);
while ($val = current($arr))
{
print "key=".key($arr).PHP_EOL;
if (!isset($arr['a']))
$arr['a'] = 'apple';
next($arr);
}
Or use ArrayIterator with foreach, because ArrayIterator is not an array.
$arr = array();
$arr['b'] = 'book';
$array_iterator = new ArrayIterator($arr);
foreach($array_iterator as $key=>$val) {
print "key=>$key\n";
if(!isset($array_iterator['a']))
$array_iterator['a'] = 'apple';
}
I think you need to store array element continue sly
Try
<?php
$arr = array();
$arr['b'] = 'book';
foreach($arr as $key=>$val) {
print "key=>$key\n";
if(!isset($arr['a']))
$arr['a'][] = 'apple';
}
print_r($arr);
?>
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
http://cz2.php.net/manual/en/control-structures.foreach.php
Try this:
You will get values.
<?php
$arr = array();
$arr['b'] = 'book';
foreach($arr as $key=>$val) {
print "key=>$key\n";
if(!isset($arr['a']))
$arr['a'] = 'apple';
}
echo '<pre>';
print_r($arr);
?>
Output:
key=>b
<pre>Array
(
[b] => book
[a] => apple
)
If you want to check key exist or not in array use array_key_exists function
Eg:
<?php
$arr = array();
$arr['b'] = 'book';
print_r($arr); // prints Array ( [b] => book )
if(!array_key_exists("a",$arr))
$arr['a'] = 'apple';
print_r($arr); // prints Array ( [b] => book [a] => apple )
?>
If you want to use isset condition try like this:
$arr = array();
$arr['b'] = 'book';
$flag = 0;
foreach($arr as $key=>$val) {
print "key=>$key\n";
if(!isset($arr["a"]))
{
$flag = 1;
}
}
if(flag)
{
$arr['a'] = 'apple';
}
print_r($arr);
How about using for and realtime array_keys()?
<?php
$arr = array();
$arr['b'] = 'book';
for ($x=0;$x<count($arr); $x++) {
$keys = array_keys($arr);
$key = $keys[$x];
print "key=>$key\n";
if(!isset($arr['a']))
$arr['a'] = 'apple';
}

PHP Can't get the right format for array

I got stuck somehow on the following problem:
What I want to achieve is to merge the following arrays based on key :
{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}
Which needs to output like this:
[{"item_header":"Entities"},
{"list_items" :
[{"submenu_id":"Parents","submenu_label":"parents"},
{"submenu_id":"Insurers","submenu_label":"insurers"}]
}]
[{"item_header":"Users"},
{"list_items" :
[{"submenu_id":"New roles","submenu_label":"newrole"}
{"submenu_id":"User - roles","submenu_label":"user_roles"}
{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}]
}]
[{"item_header":"Accounting"},
{"list_items" :
[{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}]
}]
I have been trying all kinds of things for the last two hours, but each attempt returned a different format as the one required and thus failed miserably. Somehow, I couldn't figure it out.
Do you have a construction in mind to get this job done?
I would be very interested to hear your approach on the matter.
Thanks.
$input = array(
'{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}',
'{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}',
'{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}',
'{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}',
'{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}',
'{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}',
);
$input = array_map(function ($e) { return json_decode($e, true); }, $input);
$result = array();
$indexMap = array();
foreach ($input as $index => $values) {
foreach ($values as $k => $value) {
$index = isset($indexMap[$k]) ? $indexMap[$k] : $index;
if (!isset($result[$index]['item_header'])) {
$result[$index]['item_header'] = $k;
$indexMap[$k] = $index;
}
$result[$index]['list_items'][] = $value;
}
}
echo json_encode($result);
Here you are!
In this case, first I added all arrays into one array for processing.
I thought they are in same array first, but now I realize they aren't.
Just make an empty $array=[] then and then add them all in $array[]=$a1, $array[]=$a2, etc...
$array = '[{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}},
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}},
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}},
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}},
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}},
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}]';
$array = json_decode($array, true);
$intermediate = []; // 1st step
foreach($array as $a)
{
$keys = array_keys($a);
$key = $keys[0]; // say, "Entities" or "Users"
$intermediate[$key] []= $a[$key];
}
$result = []; // 2nd step
foreach($intermediate as $key=>$a)
{
$entry = ["item_header" => $key, "list_items" => [] ];
foreach($a as $item) $entry["list_items"] []= $item;
$result []= $entry;
}
print_r($result);
I would prefer an OO approach for that.
First an object for the list_item:
{"submenu_id":"Parents","submenu_label":"parents"}
Second an object for the item_header:
{"item_header":"Entities", "list_items" : <array of list_item> }
Last an object or an array for all:
{ "Menus: <array of item_header> }
And the according getter/setter etc.
The following code will give you the requisite array over which you can iterate to get the desired output.
$final_array = array();
foreach($array as $value) { //assuming that the original arrays are stored inside another array. You can replace the iterator over the array to an iterator over input from file
$key = /*Extract the key from the string ($value)*/
$existing_array_for_key = $final_array[$key];
if(!array_key_exists ($key , $final_array)) {
$existing_array_for_key = array();
}
$existing_array_for_key[count($existing_array_for_key)+1] = /*Extract value from the String ($value)*/
$final_array[$key] = $existing_array_for_key;
}

show only duplicate values from array without builtin function PHP

For example:
$arr = array(3,5,2,5,3,9);
I want to show only common elements i.e 3,5 as output.
Here's my attempt:
<?php
$arr = array(3,5,2,5,3,9);
$temp_array = array();
foreach($arr as $val)
{
if(isset($temp_array[$val]))
{
$temp_array[$val] = $val;
}else{
$temp_array[$val] = 0;
}
}
foreach($temp_array as $val2)
{
if($val2 > 0)
{
echo $val2 . ', ';
}
}
?>
--
Output --
3, 5,
Try the following:
$arr = array(3,5,2,5,3,9);
foreach($arr as $key => $val){
//remove the item from the array in order
//to prevent printing duplicates twice
unset($arr[$key]);
//now if another copy of this key still exists in the array
//print it since it's a dup
if (in_array($val,$arr)){
echo $val . " ";
}
}
Output:
3 5
Addition:
I guess that the reason you were asked to implement it yourself (without using built-in functions) was to avoid answers like:
$unique = array_unique($arr);
$dupes = array_diff_key( $arr, $unique );
$arrnew = array();
for($i=0;$i<count($arr);$i++)
{
for($j=$i+1;$j<count($arr);$j++)
{
if($arr[$i]==$arr[$j])
{
$arrnew[]=$arr[$j];
}
}
}

Categories