Not able to create dynamic array in php - php

I am new in PHP and in below code $strng value is dynamically created for array.
$strng='"Active Life" => "6","Arts & Entertainment" => "4","Beauty & Spa" => "3","Food & Drink" => "1","Hotels" => "10","Local Services" => "8","Nightlife" => "2","Pets" => "9","Public Services" => "7","Shopping" => "5"';
$bussCatry=array($strng);
foreach($bussCatry as $x=>$x_value)
{
error_log( "Key=" . $x . ", Value=" . $x_value);
}
but when I am trying to create array I am failing I am getting below out put.
only one key value pair
Key=0,
Value="Active Life" =>"6",
"Arts & Entertainment" =>"4",
"Beauty & Spa" =>"3",
"Food & Drink" =>"1",
"Hotels" =>"10",
"Local Services" =>"8",
"Nightlife" =>"2",
"Pets" =>"9",
"Public Services" =>"7",
"Shopping" =>"5"

Check out php's array syntax.
Try this:
$bussCatry = array(
'Active Life' => '6',
'Arts & Entertainment' => '4',
'Beauty & Spa' => '3',
'Food & Drink' => '1',
'Hotels' => '10',
'Local Services' => '8',
'Nightlife' => '2',
'Pets' => '9',
'Public Services' => '7',
'Shopping' => '5',
);

array() function does not parse strings.
array("a" => "orange", "b" => "banana", "c" => "apple")
as you can see in the example there is not just a simple string, there are arguments.

Try this code you have posted wrong code.
$strng=array("Active Life" => "6","Arts & Entertainment" => "4","Beauty & Spa" => "3","Food & Drink" => "1","Hotels" => "10","Local Services" => "8","Nightlife" => "2","Pets" => "9","Public Services" => "7","Shopping" => "5");
//$bussCatry=array($strng);
foreach($strng as $x=>$x_value)
{
echo( "Key=" . $x . ", Value=" . $x_value);
}
Let me know if it works for you :)
Thanks.

Create an array directly assigned values.
$bussCatry = array(
"Active Life" => "6",
"Arts & Entertainment" => "4",
"Beauty & Spa" => "3",
"Food & Drink" => "1",
"Hotels" => "10",
"Local Services" => "8",
"Nightlife" => "2",
"Pets" => "9",
"Public Services" => "7",
"Shopping" => "5"
);
Don't convert the array values into string with single quotes. It doesn't parse like array.

Take a look at token_get_all, you can parse the string into tokens and then build your array as appropriate. Sorry it's a little messy, but it's a decent working starter.
<?php
define('STATE_WAITING_FOR_ARRAY', 1);
define('STATE_WAITING_FOR_KEY', 2);
define('STATE_WAITING_FOR_VALUE', 3);
$string = '"Active Life" => "6","Arts & Entertainment" => "4","Beauty & Spa" => "3","Food & Drink" => "1","Hotels" => "10","Local Services" => "8","Nightlife" => "2","Pets" => "9","Public Services" => "7","Shopping" => "5"';
$string = sprintf('<?php array(%s); ?>', $string);
$tokens = token_get_all($string);
$state = STATE_WAITING_FOR_ARRAY;
$array = array();
foreach($tokens as $token) {
if( ! is_array($token)) {
continue;
}
$name = token_name($token[0]);
$value = $token[1];
if(STATE_WAITING_FOR_ARRAY === $state && 'T_ARRAY' === $name) {
$state = STATE_WAITING_FOR_KEY;
continue;
}
if(STATE_WAITING_FOR_KEY === $state && 'T_CONSTANT_ENCAPSED_STRING' === $name) {
$state = STATE_WAITING_FOR_VALUE;
$key = $value;
continue;
}
if(STATE_WAITING_FOR_VALUE === $state && 'T_CONSTANT_ENCAPSED_STRING' === $name) {
$state = STATE_WAITING_FOR_KEY;
$array[$key] = $value;
$key = null;
continue;
}
}
var_dump($array);
/*
array(10) {
[""Active Life""]=>
string(3) ""6""
[""Arts & Entertainment""]=>
string(3) ""4""
[""Beauty & Spa""]=>
string(3) ""3""
[""Food & Drink""]=>
string(3) ""1""
[""Hotels""]=>
string(4) ""10""
[""Local Services""]=>
string(3) ""8""
[""Nightlife""]=>
string(3) ""2""
[""Pets""]=>
string(3) ""9""
[""Public Services""]=>
string(3) ""7""
[""Shopping""]=>
string(3) ""5""
}
*/

hmm, if this really necessary you can try this:
eval("\$bussCatry = array({$strng});");

Related

How to convert flat PHP array to indexed array

I have the following array:
'values' => [
'protein_question_0_typing_method' => '38'
'protein_question_0_amount_1' => '1'
'protein_question_0_amount_2' => '2'
'protein_question_0_units_of_measurement' => '17'
'protein_question_1_typing_method' => '39'
'protein_question_1_amount_1' => '2'
'protein_question_1_amount_2' => '2'
'protein_question_1_units_of_measurement' => '17'
'protein_question_2_typing_method' => '42'
'protein_question_2_amount_1' => '2'
'protein_question_2_amount_2' => '2'
'protein_question_2_units_of_measurement' => '17'
'distributionId' => '21'
]
How would I convert into a structure like this?
'values' => [
0 => [
'protein_question_typing_method' => '38',
'protein_question_amount_1' => '1',
'protein_question_amount_2' => '2'
],
1 => [
'protein_question_typing_method' => '42',
'protein_question_amount_1' => '1',
'protein_question_amount_2' => '2'
],
...
'distributionId' => '21'
]
This is what I've tried:
$params = \Yii::$app->request->post();
$length = count($params['values']);
for($i = 0; $i < $length; $i++) {
if(!empty($params['values']['protein_question_' . $i . '_typing_method'])) {
echo $params['values']['protein_question_' . $i . '_typing_method'] . "<br /><hr />";
}
}
The above code just prints the data, the reason I need it in the chunked format is because each chunk will be saved as a new model record in the DB.
So basically just need to convert it to an index array, anyone know the easiest way to do this as looping over the first array would be complicated?
Thanks
Can do
$input = [
'values' => [
'protein_question_0_typing_method' => '38',
'protein_question_0_amount_1' => '1',
'protein_question_0_amount_2' => '2',
'protein_question_0_units_of_measurement' => '17',
'protein_question_1_typing_method' => '39',
'protein_question_1_amount_1' => '2',
'protein_question_1_amount_2' => '2',
'protein_question_1_units_of_measurement' => '17',
'protein_question_2_typing_method' => '42',
'protein_question_2_amount_1' => '2',
'protein_question_2_amount_2' => '2',
'protein_question_2_units_of_measurement' => '17',
'distributionId' => '21'
]
];
$output = [];
foreach ($input["values"] as $key => $value) {
if (preg_match('#^protein_question_(\d+)_(.+)$#', $key, $match)) {
$output[$match[1]]['protein_question_' . $match[2]] = $value;
} else {
$output[$key] = $value;
}
}
var_dump($output);
This will iterate over all the keys in the array and match if the start with protein_question, followed by a number, followed by some text. If so, the number is used as the index in the output to hold the key minus the number along with the value. If it doesnt match, the key and value are put as is.
Will give
array(4) {
[0]=>
array(4) {
["protein_question_typing_method"]=>
string(2) "38"
["protein_question_amount_1"]=>
string(1) "1"
["protein_question_amount_2"]=>
string(1) "2"
["protein_question_units_of_measurement"]=>
string(2) "17"
}
[1]=>
array(4) {
["protein_question_typing_method"]=>
string(2) "39"
["protein_question_amount_1"]=>
string(1) "2"
["protein_question_amount_2"]=>
string(1) "2"
["protein_question_units_of_measurement"]=>
string(2) "17"
}
[2]=>
array(4) {
["protein_question_typing_method"]=>
string(2) "42"
["protein_question_amount_1"]=>
string(1) "2"
["protein_question_amount_2"]=>
string(1) "2"
["protein_question_units_of_measurement"]=>
string(2) "17"
}
["distributionId"]=>
string(2) "21"
}
Here a very basic implementation to get you started, you may want to adjust it to your specific needs:
<?php
$values = [
'protein_question_0_typing_method' => '38',
'protein_question_0_amount_1' => '1',
'protein_question_0_amount_2' => '2',
'protein_question_0_units_of_measurement' => '17',
'protein_question_1_typing_method' => '39',
'protein_question_1_amount_1' => '2',
'protein_question_1_amount_2' => '2',
'protein_question_1_units_of_measurement' => '17',
'protein_question_2_typing_method' => '42',
'protein_question_2_amount_1' => '2',
'protein_question_2_amount_2' => '2',
'protein_question_2_units_of_measurement' => '17',
'distributionId' => '21'
];
function convert($values) {
$result = [];
foreach ($values as $key => $value) {
$matches = [];
$ret = preg_match('~^protein_question_([0-9]+)_~U', $key, $matches);
// Key does not match the pattern protein_question_*_
if ($ret !== 1) {
$result[$key] = $value;
continue;
}
$proteinQuestionID = (int)$matches[1];
// Create key for the this ID
if (!isset($result[$proteinQuestionID])) {
$result[$proteinQuestionID] = [];
}
// Adjust the key...
$key = \substr($key, \strlen('protein_question_'.$proteinQuestionID));
$key = 'protein_question'.$key;
// Append to it...
$result[$proteinQuestionID][$key] = $value;
}
return $result;
}
print_r(convert($values));
did you tried array_chunk($your_array, 4) . it looks this method can help you

Php find key for min value in 2D array

I have the following 2D array and I would like to get the key of the smalest value in the [0] column if done is equal to no
$graph= array(
"CityA" => array(
"0" => "1",
"1" => "CityC",
"done" => "no",
),
"CityB" => array(
"0" => "4",
"1" => "CityA",
"done" => "no",
),
"CityC" => array(
"0" => "5",
"1" => "CityA",
"done" => "no",
),
);
Try this,
$arr = array_map(function($v){return $v[0];}, $graph);
$key = array_keys($arr, min($arr));
Here you go.
$tes = min( array_column( $graph, 0 ) );
$key = array_search( $tes, array_column( $graph, 0 ) );
$array_keys = array_keys($graph);
echo $array_keys[$key];
You should perform all of your checks in a single pass through your array.
My snippet will provide the first qualifying (contains the lowest [0] value AND has a done value of no) row's key.
Code: (Demo)
$graph = [
"CityB" => ["0" => "1", "1" => "CityA", "done" => "no"],
"CityA" => ["0" => "1", "1" => "CityC", "done" => "no"],
"CityD" => ["0" => "1", "1" => "CityD", "done" => "yes"],
"CityC" => ["0" => "5", "1" => "CityA", "done" => "no"]
];
$result = [];
foreach ($graph as $key => $row) {
if ($row['done'] === 'no' && (!isset($result[$key]) || $row[0] < $result[$key])) {
$result[$key] = $row[0];
}
}
echo key($result) ?? 'No "done => no" rows';
Output:
CityB

Preg match array keys

I have it like this:
$data = array(
"City_0" => "London",
"City_1" => "Paris",
"City_2" => "Lisbon",
"City_3" => "Berlin"
);
plus some other data in that same array.
User will select only one of these and what I need is:
Check with preg_match to get all keys that starts with "city_"
find key which has value (it is not empty), take that value
assign it to new key
remove all "city_" keys
add new key to array with the name "chosen_city" which will contain that value
What I tried:
foreach ($data as $key => $value) {
$matches = preg_match('/city_/i', $key);
if ($value != "") {
$newValue = $value;
break;
}
}
$data['chosen_city'] = $newValue;
print_r($data);
This works partially, how can I remove all previous "city_" keys from array in that if statement?
NOTE:
I have other keys in array, and I don't want to remove them as well.
Input array:
$data = array(
"City_0" => "London",
"City_1" => "Paris",
"City_2" => "Lisbon",
"City_3" => "Berlin",
"distance" => "5 km",
"days" => "7",
"tickets" => "2",
"discount" => "10%",
);
Expected output:
$data = array(
"chosen_city" => "Berlin",
"distance" => "5 km",
"days" => "7",
"tickets" => "2",
"discount" => "10%",
);
Thanks.
Please put unset for example code :
$data = array( "City_0" => "London", "City_1" => "Paris", "City_2" => "Lisbon", "City_3" => "Berlin");
foreach($data as $key => $value){
$matches = preg_match('/city_/i', $key);
if($matches && $value != ""){
$newValue = $value;
unset($data[$key]);
}elseif($matches){
unset($data[$key]);
}
}
$data['chosen_city'] = $newValue;
preg_* is somewhat overkill in this instance - you could use strpos and it'd work just as well
However, the question is 'how to I remove the city_* keys', so to do that, just use unset():
foreach($data as $key => $value){
$matches = preg_match('/city_/i', $key);
if($value != ""){
$newValue = $value;
unset($data[$key]); //Remove this item from the array
break;
}
}
$data['chosen_city'] = $newValue;
print_r($data);
$data = array(
"City_0" => "London",
"City_1" => "Paris",
"City_2" => "Lisbon",
"City_3" => "Berlin",
"distance" => "5 km",
"days" => "7",
"tickets" => "2",
"discount" => "10%",
);
$value = 'Berlin';
if (array_search($value, $data)) {
$data['chosen_city'] = $value;
foreach ($data as $key=>$val) {
if (stripos($key, 'city_')===0) {
unset($data[$key]);
}
}
}
result:
array(5) {
'distance' =>
string(4) "5 km"
'days' =>
string(1) "7"
'tickets' =>
string(1) "2"
'discount' =>
string(3) "10%"
'chosen_city' =>
string(6) "Berlin"
}
If you use PHP >=5.6, probably you can use (I didn't tested this code)
$city = array_search($value, $data);
if ($city) {
$data['chosen_city'] = $value;
$data = array_filter($data,function($key,$val){return stripos($key,'city_')===false;},ARRAY_FILTER_USE_BOTH);
}

If value between array key

Example i have this array:
$ar = array(
"1.00" => array("value0"," very bad"),
"1.49" => array("value1","bad"),
"2.00" => array("value2","not bad"),
"2.49" => array("value3","normal"),
"3.00" => array("value4","good"),
"3.49" => array("value5","very good")
);
I want to check if $val is under 1.00 the $result is array("value0"," very bad"). if between range 1.00 - 1,49 the result is array("value1","bad"), etc.
Anyone can help me?
Here is a hint :
<?php
$ar = array(
"1.00" => array("value0"," very bad"),
"1.49" => array("value1","bad"),
"2.00" => array("value2","not bad"),
"2.49" => array("value3","normal"),
"3.00" => array("value4","good"),
"3.49" => array("value5","very good")
);
$input = 1.2;
foreach($ar as $key=>$text)
{
if($input < floatval($key))
{
echo $text[0].' => '.$text[1];
break;
}
}
?>
$val = '2.15';
$val_data = ['value2','not bad'];
$data = array(
"1.00" => array("value0"," very bad"),
"1.49" => array("value1","bad"),
"2.00" => array("value2","not bad"),
"2.49" => array("value3","normal"),
"3.00" => array("value4","good"),
"3.49" => array("value5","very good")
);
$_fkey = array_keys($data)[0];
foreach($data as $key => $value){
if($key > $_fkey && $key < $val){$_fkey = $key;}
}
echo "$val, $val_data\n";
echo "=> $f_key, " . $data[$f_key] . "\n";

Group array values based on key in php? [duplicate]

This question already has answers here:
How to group subarrays by a column value?
(20 answers)
Closed 11 months ago.
I have a array like this:
$str=
Array
(
[No] => 101
[Paper_id] => WE3P-1
[Title] => "a1"
[Author] => ABC
[Aff_list] => "University of South Florida, Tampa, United States"
[Abstracts] => "SLA"
)
Array
(
[No] => 101
[Paper_id] => WE3P-1
[Title] => "a2"
[Author] => DEF
[Aff_list] => "University of South Florida, Tampa, United States"
[Abstracts] => "SLA "
)
Array
(
[No] => 104
[Paper_id] => TU5A-3
[Title] => "a3"
[Author] => GHI
[Aff_list] => "University of Alcala, Alcala de Henares, Spain"
[Abstracts] => "Microwave"
)
I want to group elements in the array based upon 'No' as primary key. The output should look like this:
array(6) {
["No"]=>
string(6) "101"
["Paper_id"]=>
string(6) "WE3P-1"
["Title"]=>
string(80) ""a-1"
["Author"]=>
string(14) "ABC"
["Aff_list"]=>
string(51) ""University of South Florida, Tampa, United States""
["Abstracts"]=>
string(5) ""(SLA)"
"
}
array(6) {
["No"]=>
string(3) "104"
["Paper_id"]=>
string(6) "TU5A-3"
["Title"]=>
string(40) "a2"
["Author"]=>
string(20) "DEF"
["Aff_list"]=>
string(48) ""University of Alcala, Alcala de Henares, Spain""
["Abstracts"]=>
string(9) ""Microwave"
"
}
Note that the Author's value got merged with respect to the primary key 'No'.Can anyone help me out from this, please?
I tried doing this:
foreach($paper_info as $element) {
foreach($element as $v) {
$id = $element['No'];
if (!isset($out[$id])) {
$out[$id] = [
'No' => $element['No'],
'Paper_id' => $element['Paper_id'],
'Title' => $element['Title'],
'Authors' => [],
'Aff_list' => $element['Aff_list'],
'Abstracts' => $element['Abstracts']
];
}
$out[$id]['Authors'][] = ['Authors' => $element['Author']];
}
}
You could use a generic function:
function _group_by($array, $key) {
$return = array();
foreach($array as $val) {
$return[$val[$key]][] = $val;
}
return $return;
}
I added some sample code to test
<?php
$list= [
[ 'No' => 101,
'Paper_id' => 'WE3P-1',
'Title' => "a1",
'Author' => 'ABC',
'Aff_list' => "University of South Florida, Tampa, United States",
'Abstracts' => "SLA"
] ,
[ 'No' => 101,
'Paper_id' => 'WE3P-1',
'Title' => "a2",
'Author' => 'DEF',
'Aff_list' => "University of South Florida, Tampa, United States",
'Abstracts' => "SLA"
] ,
[ 'No' => 104,
'Paper_id' => 'TUSA-3',
'Title' => "a3",
'Author' => 'GH1',
'Aff_list' => "University of Alcala, Alcala de Henares, Spain",
'Abstracts' => "Microwave"
] ];
print_r(_group_by($list, 'No'));
The data format in your question is ambiguous, but assuming the structure for $paper_info is what is below, this should get you the output you're looking for.
$paper_info = array(
array(
'No' => "101",
'Paper_id' => "WE3P-1",
'Title' =>"An Electrically-Small, 3-D Cube Antenna Fabricated with Additive Manufacturing",
'Author' => "Ibrahim Nassar",
...
),
array(
'No' => "101",
...
'Author' => "Thomas Weller",
...
)
);
$out = array();
foreach($paper_info as $paper) {
$id = $paper['No'];
if (!isset($out[$id])) {
$out[$id] = $paper;
$out[$id]['Author'] = array();
}
$out[$id]['Author'][] = $paper['Author'];
}
You should also turn on warnings and display errors in your development environment. I have a feeling it will help you. During development you can either configure your php.ini, or insert this code at the beginning of your php script. Just make sure you remove it before pushing to production.
error_reporting(E_ALL);
ini_set('display_errors', '1');
Thanks to crafter for the awesome function, if someone need to group for multiple keys i edited the crafter function to this:
function _group_by($array, $keys=array()) {
$return = array();
foreach($array as $val){
$final_key = "";
foreach($keys as $theKey){
$final_key .= $val[$theKey] . "_";
}
$return[$final_key][] = $val;
}
return $return;
}
Thanks to crater and Fabio's answer. I updated the code to check if the size of the key is not greater than one (1), underscore will not be appended.
function _group_by($array, $keys=array()) {
$return = array();
$append = (sizeof($keys) > 1 ? "_" : null);
foreach($array as $val){
$final_key = "";
foreach($keys as $theKey){
$final_key .= $val[$theKey] . $append;
}
$return[$final_key][] = $val;
}
return $return;
}
I have wrote an another version of Crafter's answer which is remove given key from actual array. May help someone.
public function _group_by($array, $key) {
$return = array();
foreach($array as $val) {
$return[$val[$key]] = $val;
unset($return[$val[$key]][$key]);
}
return $return;
}

Categories