Populate a previously created associative array, with values - php

Trying to populate a previously created associative array, with values where values are randomly created. I cannot spot what I am doing wrong.
<?php
$value_min = 1;
$value_max = 3;
$my_array = array (
"dice_1" => null,
"dice_2" => null,
"dice_3" => null
);
foreach(range($value_min, $value_max) as $key => $value) {
$my_array[] = random_int($value_min, $value_max);
};
print_r($my_array);
Outcome:
Array
(
[dice_1] =>
[dice_2] =>
[dice_3] =>
[0] => 2
[1] => 2
[2] => 3
)
Expected outcome
(
[dice_1] => 2
[dice_2] => 2
[dice_3] => 3
)
Note: value can of course diff since they are created with random numbers

just change the foreach
foreach($my_array as $key => $value) {
$my_array[$key] = random_int($value_min, $value_max);
};

Here you can do something like this,
$t = range($value_min, $value_max);
shuffle($t);
$temp = array_combine(array_keys($my_array), $t);
I am fetching keys of $my_array and shuffled range array.
Then combining them as keys as first argument and shuffled range array as second argument.
Demo.
EDIT
In that case you can traverse my_array,
foreach($my_array as $key => &$value) { // & to save data directly to its address
$value = random_int($value_min, $value_max);
};
Demo.

$value_min = 1;
$value_max = 3;
$my_array = array (
"dice_1" => null,
"dice_2" => null,
"dice_3" => null
);
$i=1;
foreach(range($value_min, $value_max) as $key => $value) {
$my_array["dice_".$i] = random_int($value_min, $value_max);
$i++;
};
print_r($my_array);
DEMO

Related

Group data by leading portion of keys and push values into each group as indexed elements

I have the following working code that from 2 separate arrays ($I & $f) creates final multidimension array with the data as associated columns.
The problem is i feel the code is clunky, but i cant see if, or how it could me improved. So I'm hoping a second pair of eyes can help.
<?php
//main array of input data
$i = [ 'input_tickettype1_storeno_00' => null,
'input_tickettype1_deliverydate_00' => null,
'input_tickettype1_ticketref_00' => null,
'input_tickettype1_storeno_01' => '9874',
'input_tickettype1_deliverydate_01' => '2022-02-01',
'input_tickettype1_ticketref_01' => 'EDN6547',
'input_tickettype1_storeno_02' => '8547',
'input_tickettype1_deliverydate_02' => '2022-01-31',
'input_tickettype1_ticketref_02' => 'EDN5473',
'input_tickettype1_storeno_03' => '9214',
'input_tickettype1_deliverydate_03' => '2022-02-28',
'input_tickettype1_ticketref_03' => 'EDN1073'
];
//headers
$h = [ 'input_tickettype1_storeno' ,
'input_tickettype1_deliverydate',
'input_tickettype1_ticketref'
];
//final multidim array
$f = array();
//Create a multidim for the headers and the values
foreach ($h as $k => $v)
{
$f[] = [$v=>null];
}
//loop throught the headers looping for matches in the input data
for ($x = 0; $x < count($f); $x++) {
foreach ($f[$x] as $fk => $fv) {
foreach ($i as $ik => $iv) {
if (str_contains($ik,$fk)) {
array_push($f[$x],$iv);
}
}
}
}
print_r($f);
//Actual Working Output
// Array (
// [0] => Array ( [input_tickettype1_storeno] =>
// [0] =>
// [1] => 9874
// [2] => 8547
// [3] => 9214
// )
// [1] => Array ( [input_tickettype1_deliverydate] =>
// [0] =>
// [1] => 2022-02-01
// [2] => 2022-01-31
// [3] => 2022-02-28
// )
// [2] => Array ( [input_tickettype1_ticketref] =>
// [0] =>
// [1] => EDN6547
// [2] => EDN5473
// [3] => EDN1073
// )
// )
?>
Yes, indeed I think the code can be optimised for readability and logic.
I can think of two methods you can use.
Method 1 : nested foreach
First of all, you don't need a foreach to initialize your multidimentional array, you can do it within the main loop you use to read the data. So you can remove the foreach -- $f[] = [$v=>null];
Then, instead of having 1 for and 2 foreach you can just have 2 foreach one for each array and use a very fast strpos to identify if the key matches and populate the final array.
Here's the resulting code.
$f = [];
foreach ($h as $prefix) {
$f[$prefix] = [];
foreach ($i as $key => $val) {
if (strpos($key, $prefix) === 0) {
$f[$prefix][] = $val;
}
}
}
This first method is simple, with a straightforward logic. However it requires a nested foreach. Which means that if both arrays get larger, your code gets much slower.
Method 2 : key manipulation
This method assumes that the keys of the first array never change structure and they are always somestringid_[digits]
In this case we can avoid looping the second array and just use a regular expression to recreate the key.
$f = [];
foreach ($i as $key => $value) {
preg_match('/^(.*)_[0-9]+$/', $key, $m);
$key = $m[1];
if (empty($f[$m[1]])) {
$f[$m[1]] = [];
}
$f[$m[1]][] = $value;
}
I don't see any need to implement any additional data or conditions. You only need to read your main array, mutate the keys (trim the trailing unique identifiers) as you iterate, and push data into their relative groups.
Code: (Demo)
$result = [];
foreach ($array as $k => $v) {
$result[preg_replace('/_\d+$/', '', $k)][] = $v;
}
var_export($result);
Output:
array (
'input_tickettype1_storeno' =>
array (
0 => NULL,
1 => '9874',
2 => '8547',
3 => '9214',
),
'input_tickettype1_deliverydate' =>
array (
0 => NULL,
1 => '2022-02-01',
2 => '2022-01-31',
3 => '2022-02-28',
),
'input_tickettype1_ticketref' =>
array (
0 => NULL,
1 => 'EDN6547',
2 => 'EDN5473',
3 => 'EDN1073',
),
)

Split flat array into grouped subarrays containing values from consecutive key in the input array

I have an array from array_diff function and it looks like below:
Array
(
[0] => world
[1] => is
[2] => a
[3] => wonderfull
[5] => in
[6] => our
)
As you can see, we have a gap between the keys #3 and #5 (i.e. there is no key #4).
How can I split that array into 2 parts, or maybe more if there are more gaps?
The expected output would be:
Array
(
[0] => Array
(
[0] => world
[1] => is
[2] => a
[3] => wonderfull
)
[1] => Array
(
[0] => in
[1] => our
)
)
You can use old_key,new_key concept to check that there difference is 1 or not? if not then create new index inside you result array otherwise add the values on same index:-
<?php
$arr = Array(0 => 'world',1 => 'is',2 => 'a',3 => 'wonderfull',5 => 'in',6 => 'our');
$new_array = [];
$old_key = -1;
$i = 0;
foreach($arr as $key=>$val){
if(($key-$old_key) ==1){
$new_array[$i][] = $val;
$old_key = $key;
}
if(($key-$old_key) >1){
$i++;
$new_array[$i][] = $val;
$old_key = $key;
}
}
print_r($new_array);
https://3v4l.org/Yl9rp
You can make use of the array internal pointer to traverse the array.
<?php
$arr = Array(0=>"world",1=>"is",2=>"a",3=>"wonderfull",5=>"in",6=>"our");
print_r($arr);
$result = Array();
$lastkey;
while($word = current($arr))
{
$key = key($arr);
if(isset($lastkey) && $key == $lastkey + 1)
{
$result[count($result) - 1][] = $word;
}
else
{
$result[] = Array($word);
}
$lastkey = $key;
next($arr);
}
print_r($result);
?>
This task is a perfect candidate for a reference variable. You unconditionally push values into a designated "bucket" -- in this case a subarray. You only conditionally change where that bucket is in the output array.
There are two important checks to make when determining if a new incremented key should be generated:
if it is not the first iteration and
the current key minus (the previous key + 1) does not equal 0.
Code: (Demo)
$nextKey = null;
$result = [];
foreach ($array as $key => $val) {
if ($nextKey === null || $key !== $nextKey) {
unset($ref);
$result[] = &$ref;
}
$ref[] = $val;
$nextKey = $key + 1;
}
var_export($result);
This solution generates an indexed array starting from zero with my sample input and uses only one if block. In contrast, AliveToDie's solution generates a numerically keyed array starting from 1 and uses two condition blocks containing redundant lines of code.

Count how many times a value appears in this array?

I have this php array named $ids:
Array (
[0] => Array ( [id] => 10101101 )
[1] => Array ( [id] => 18581768 )
[2] => Array ( [id] => 55533322 )
[3] => Array ( [id] => 55533322 )
[4] => Array ( [id] => 64621412 )
)
And I need to make a new array containing each $ids id value, as the new keys, and the times each one appears, as the new values.
Something like this:
$newArr = array(
10101101 => 1,
18581768 => 1,
55533322 => 2,
64621412 => 1,
);
This is what I have:
$newArr = array();
$aux1 = "";
//$arr is the original array
for($i=0; $i<count($arr); $i++){
$val = $arr[$i]["id"];
if($val != $aux1){
$newArr[$val] = count(array_keys($arr, $val));
$aux1 = $val;
}
}
I supose array_keys doesn't work here because $arr has the id values in the second dimension.
So, how can I make this work?
Sorry for my bad english and thanks.
array_column will create an array of all the elements in a specific column of a 2-D array, and array_count_values will count the repetitions of each value in an array.
$newArr = array_count_values(array_column($ids, 'id'));
Or do it by hand like this where $arr is your source array and $sums is your result array.
$sums = array();
foreach($arr as $vv){
$v = $vv["id"];
If(!array_key_exists($v,$sums){
$sums[$v] = 0;
}
$sums[$v]++;
}
You can traverse your array, and sum the id appearance, live demo.
$counts = [];
foreach($array as $v)
{
#$counts[$v['id']] += 1;
}
print_r($counts);

Merge keys of an array based on values

I want to merge the keys of array based on values. This is my array.
Array
(
[1] => 1
[2] => 1
[3] => 1
[4] => 2
[5] => 0
[6] => 2
[7] => 2
)
I want output as
Array
(
[1,2,3] => 1
[4,6,7] => 2
[5] => 0
)
I have been brain storming entire day but couldn't find a solution. Any hint would be much appreciated.
WHAT I HAVE TRIED:
for($i=2;$i<=count($new);$i++){
if ($new[$i-1][1]==$new[$i][1]){
$same .= $new[$i-1][0].$new[$i][0];
}
}
echo $same;
But I am stucked. I am comparing the keys one by one but it's very complicated. I don't need the code. I only need the hint or logic. Anyone kind enough?
<?php
$old_arr = ["1"=>1,"2"=>1,"3"=>1,"4"=>2,"5"=>0,"6"=>2,"7"=>2];
$tmp = array();
foreach($old_arr as $key=>$value)
{
if(in_array($value, $tmp)){
$index = array_search($value, $tmp);
unset($tmp[$index]);
$tmp[$index.",".$key] = $value;
}else{
$tmp[$key] = $value;
}
}
ksort($tmp);
echo "<pre>";
print_r($tmp);
echo "</pre>";
?>
https://eval.in/529314
You can loop through array elements and create a new array with new structure. Please check the below code it may help you
$old_array = array(1=> 1,2 => 1,
3=> 1,
4 => 2,
5 => 0,
6 => 2,
7 => 2
);
$new_array = array();
foreach($old_array as $key => $value)
{
if(in_array($value,$new_array))
{
$key_new = array_search($value, $new_array);//to get the key of element
unset($new_array[$key_new]); //remove the element
$key_new = $key_new.','.$key; //updating the key
$new_array[$key_new] = $value; //inserting new element to the key
}
else
{
$new_array[$key] = $value;
}
}
print_r($new_array);
$arr = array(1 => 1, 2 => 1, 3 => 1, 4 => 2, 5 => 0, 6 => 2, 7 => 2);
$tmp = array();
foreach ($arr as $key => $val)
$tmp[$val][] = $key;
$new = array();
foreach ($tmp as $key => $val)
$new[implode(',', $val)] = $key;
First loop the original array through, creating a temporary array, where your original values are keys and values are the original keys as an array.
Then loop the temporary array, creating the new array, where the temporary array's values are imploded as keys.
There's no way to have an array of keys to a single value, but the other way around:
function flipWithKeyArray($arr){
$result = array();
foreach($arr as $key => $val){
if(!isset($result[$val]))
$result[$val] = array();
$result[$val][] = $key;
}
return $result;
}
This will flip your array and declare one array per value of your old array and then push the keys with the same value into each list.
For an array like this:
array(1=>1, 2=>1, 3=>1, 4=>2, 5=>2, 6=>2)
The result will look like this:
array(1=>array(1,2,3), 2=>array(4,5,6))
Hope it fits your need.

transfer specific index of array to a new array - php

I want to delete an index from array and insert it into in new array. I want two things which i tried to explain one is
Array
(
[index1] => Deleted
[index4] => Inserted
)
Array
(
[index3] => test
[index4] => Inserted
)
Array
(
[index2] => numbers
[index3] => test
[index4] => Inserted
)
Array
(
[index1] => Deleted
)
now i want if arraysize is 1
foreach($array as $arrays){
array_push($array1,($arrays[0]));
unset ($arrays[0]);
}
i want to remove
Array
(
[index1] => Deleted
)
from $array and $array to be
[index1] => Deleted
second is if $array is
Array
(
[index2_123] => numbers
[index3_level] => test
[index4_test] => Inserted
)
i want a new array with $array1 as
Array
(
[index3_level] => test
)
and $array1 is modified to
Array
(
[index2_123] => numbers
[index4_test] => Inserted
)
Try this way,
$arr = Array
(
'index1' => 'Deleted',
'index2' => 'numbers',
'index3' => 'test',
'index4' => 'Inserted'
);
$arr1 = $arr2 = array();
$i = 0;
foreach($arr as $key => $value){
if($i%2 == 0){
$arr1[$key] = $value;
}else{
$arr2[$key] = $value;
}
$i++;
}
Output
$arr1
Array
(
[index1] => Deleted
[index3] => test
)
$arr2
Array
(
[index2] => numbers
[index4] => Inserted
)
And if you don't need that value then you can use it as
$i = 0;
foreach($arr as $key => $value){
if($i%2 == 0){
$arr[$key] = $value;
}else{
unset($arr[$key]);
}
$i++;
}
print_r($arr);
Output:
Array
(
[index1] => Deleted
[index3] => test
)
Loop through them and generate the array -
$new = array();
foreach($yourarray as $key => $val) {
$index = str_replace('index', '', $key); // get the key index
if($index % 2 != 0) { // check for odd or even
$new[$key] = $val; // set the new array
unset($yourarray[$key]); // delete from the main array
}
}
Update
For any index use a counter
$i = 0;
$new = array();
foreach($yourarray as $key => $val) {
if($i % 2 != 0) { // check for odd or even
$new[$key] = $val; // set the new array
unset($yourarray[$key]); // delete from the main array
}
$i++;
}
You can use a combination of array_flip and array_diff_key to filter the first array, then use array_diff filter the second:
$specificIndex = array('index1', 'index3');
$array1 = array_diff_key($array, array_flip($specificIndex));
$array2 = array_diff($array, $array1);
Demo.
If you want get in an array only certain elements of your choice you can do something like:
$specificIndex = array('index1', 'index3');
$selectedItem = array_intersect_key($array, array_flip($specificIndex));
Demo.
<?php
$array = array(
'index1' => 'Deleted',
'index2' => 'numbers',
'index3' => 'test',
'index4' => 'Inserted',
);
$specificIndex = 'index3';
$array1=array();
foreach($array as $key => $value){
if($key==$specificIndex){
$array1[$key] = $value;
unset($array[$specificIndex]);
}
}
print_r($array);
print_r($array1);
http://3v4l.org/TvZ19

Categories