This is my data:
$d = $request->request->get('data');
The output:
[{"name":"form[id]","value":"10"},{"name":"form[name]","value":"Telefon2"},{"name":"form[uuid]","value":"bb80878ad4"},{"name":"form[productgroup]","value":"6"},{"name":"form[category]","value":"1"},{"name":"form[documents]","value":"7"}
I want to create a new array, that is removing extracting the variable inside the brackets.
function trim($d) {
preg_match('#\[(.*?)\]#', $d, $match);
return $match[1];
}
$dData = array_combine(array_column(trim($d), 'name'), array_column($d, 'value'));
$json = json_encode($dData);
But the error is
Warning: preg_match() expects parameter 2 to be string, array given
You're going to need to do a few things before you begin.
Firstly, rename the trim function to something like extract_name because PHP already has a built in trim function that removes whitespace from a string - or any character present in the character mask.
Secondly, you are going to need to iterate over each of the elements in the name column. You will notice the error you are getting from preg_match is because you are passing all values in one go.
Thirdly, I am assuming that the value of $d is an array of PHP objects. This is done, and assumed, in my solution using $d = json_decode($d);.
Using array_map instead of a foreach means we can have a nice one liner:
function extract_name($d) {
preg_match('#\[(.*?)\]#', $d, $match);
return $match[1];
}
$dData = array_combine(array_map('extract_name', array_column($d, 'name')), array_column($d, 'value'));
The output being:
array:6 [
"id" => "10"
"name" => "Telefon2"
"uuid" => "bb80878ad4"
"productgroup" => "6"
"category" => "1"
"documents" => "7"
]
Live demo
I believe you need smth like this
$d = ['{"name":"form[id]","value":"10"}', '{"name":"form[name]","value":"Telefon2"}', '{"name":"form[uuid]","value":"bb80878ad4"}', '{"name":"form[productgroup]","value":"6"}'];
function combine(array $d): array
{
$res = [];
foreach ($d as $item) {
$value = json_decode($item, true);
preg_match('#\[(.*?)\]#', $value['name'], $match);;
$columnName = $match[1];
$res[$columnName] = $value['value'];
}
return $res;
}
$dData = combine($d);
$json = json_encode($dData);
echo $json;```
Related
I have 2 arrays.
$first = [
'01/10/2019' =>
[
21498226,
21497647,
21497649,
21497635,
21497636,
21497637,
21497728,
21497822,
21498028,
21497638,
],
];
$second = [
'01/10/2019' =>
[
21498226,
21497647,
12345678,
87654321,
21497636,
21497637,
21497728,
21497822,
21498028,
21497638,
],
];
I have written this code
$notPresent = [];
foreach ($second as $date => $code) {
foreach ($code as $c) {
if (array_key_exists($date, $first)) {
if (!in_array($c, $first[$date])) {
$notPresent[$date] = $code;
}
} else {
$notPresent[$date] = $code;
}
}
}
But it is returning me all 10 values. What I really want is to have only those values that are not present in $first. Like 12345678 and 87654321.
Swap the arrays around so that you are looking for elements of array 2 that are not in array 1, and that's word-for-word what array_diff does.
returns the values in array1 that are not present in any of the other arrays
You will need to iterate over the "parent" arrays, naturally, so array_map can help too. (Although, to preserve the keys, you'll need some fiddling around with array_keys and array_combine since array_map doesn't preserve keys...)
$notPresent = array_combine(
array_keys($second),
array_map('array_diff', $second, $first)
);
EDIT I just realised that the above code assumes that the keys exist in both arrays in the same order. Since that's almost certainly not the case, here's an adjusted version that handles that.
$notPresent = array_combine(
array_keys($second),
array_map(function($key,$values) use ($first) {
if( array_key_exists($key,$first)) {
return array_diff($values, $first[$key]);
}
return $values;
}, array_keys($second), array_values($second))
);
I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);
I'm trying to find out if there's any function that would split a string like:
keyword=flower|type=outdoors|colour=red
to array:
array('keyword' => 'flower', 'type' => 'outdoors', 'colour' => 'red')
At the moment I built a custom function, which uses explode to first split elements with the separator | and then each of those with assignment symbol =, but is there perhaps a native function which would do it out of the box by specifying the string separator?
The function I've written looks like this:
public static function splitStringToArray(
$string = null,
$itemDivider = '|',
$keyValueDivider = '='
) {
if (empty($string)) {
return array();
}
$items = explode($itemDivider, $string);
if (empty($items)) {
return array();
}
$out = array();
foreach($items as $item) {
$itemArray = explode($keyValueDivider, $item);
if (
count($itemArray) > 1 &&
!empty($itemArray[1])
) {
$out[$itemArray[0]] = $itemArray[1];
}
}
return $out;
}
$string = "keyword=flower|type=outdoors|colour=red";
$string = str_replace('|', '&', $string);
parse_str($string, $values);
$values=array_filter($values); // Remove empty pairs as per your comment
print_r($values);
Output
Array
(
[keyword] => flower
[type] => outdoors
[colour] => red
)
Fiddle
Use regexp to solve this problem.
([^=]+)\=([^\|]+)
http://regex101.com/r/eQ9tW8/1
The issue is that your chosen format of representing variables in a string is non-standard. If you are able to change the | delimiter to a & character you would have (what looks like) a query string from a URL - and you'll be able to parse that easily:
$string = "keyword=flower&type=outdoors&colour=red";
parse_str( $string, $arr );
var_dump( $arr );
// array(3) { ["keyword"]=> string(6) "flower" ["type"]=> string(8) "outdoors" ["colour"]=> string(3) "red" }
I would recommend changing the delimiter at the source instead of manually replacing it with replace() or something similar (if possible).
I have php script as below;
$ages = array("Peter"=>32, "Quagmire"=>30, "Joe"=>34);
$ages2 = '"Peter"=>32, "Quagmire"=>30, "Joe"=>34';
$array = explode(",", $ages2);
echo $array["Peter"];
echo $ages["Peter"];
In this case, echo $ages["Peter"]; is working well, but echo $array["Peter"]; is not working. Can anybody solve this please..
Thanks in advance.
blasteralfred
You'll have to go in two steps :
First, explode using ', ', as a separator ; to get pieces of data such as "Peter"=>32
And, then, for each value, explode using '=>' as a separator, to split the name and the age
Removing the double-quotes arround the name, of course.
For example, you could use something like this :
$result = array();
$ages2 = '"Peter"=>32, "Quagmire"=>30, "Joe"=>34';
foreach (explode(', ', $ages2) as $couple) {
list ($name, $age) = explode('=>', $couple);
$name = trim($name, '"');
$result[$name] = $age;
}
var_dump($result);
And, dumping the array, you'd get the following output :
array
'Peter' => string '32' (length=2)
'Quagmire' => string '30' (length=2)
'Joe' => string '34' (length=2)
Which means that using this :
echo $result['Peter'];
Would get you :
32
Of course it doesn't work. explode just splits by the given delimiter but doesn't create an associative array.
Your only hope if you really have such a string is to parse it manually. Either using preg_match_all, or I suppose you could do:
$array = eval('return array('.$ages2.');');
But of course this isn't recommended since it could go wrong in many many ways.
In any case I'm pretty sure you can refactor this code or give us more context if you need more help.
You'll need to build the array yourself by extracting the name and age:
<?php
$array = array();
$ages2 = '"Peter"=>32, "Quagmire"=>30, "Joe"=>34';
foreach (explode(",", $ages2) as $element) {
$parts = explode("=>", $element);
if (count($parts) == 2) {
$name = str_replace(array('"', ' '), '', $parts[0]);
$age = (int) $parts[1];
$array[$name] = $age;
}
}
print_r($array);
$ages2 is not an array, so what you're trying here won't work directly, but you can transform a string with that structure into an array like this:
$ages2 = '"Peter"=>32, "Quagmire"=>30, "Joe"=>34';
$items = explode(",", $ages2);
foreach ($items as $item) {
list($key,$value) = explode('=>',$item);
$key = str_replace('"','',trim($key)); // Remove quotes and trim whitespace.
$array[$key] = (int)$value;
}
If you var_dump($array), you'll have:
array(3) {
["Peter"]=>
int(32)
["Quagmire"]=>
int(30)
["Joe"]=>
int(34)
}
So you can do this as expected and get 32 back out:
echo $array['Peter']
I want to convert this array that Array[4] should not give null it can give blank space (empty string).
Array (
[0] => 1
[1] => 4
[2] => 0
[3] => V
[4] =>
[5] => N
);
(The reason for the change, unrelated to the general question)
Fatal error: Uncaught exception
'PDOException' with message 'Database
error [23000]: Column 'message' cannot
be null, driver error code is 1048' in
PHP 5.3+
$array = array_map(function($v){
return (is_null($v)) ? "" : $v;
},$array);
Then you should just loop through array elements, check each value for null and replace it with empty string. Something like that:
foreach ($array as $key => $value) {
if (is_null($value)) {
$array[$key] = "";
}
}
Also, you can implement checking function and use array_map() function.
There is even better/shorter/simpler solution. Compilation of already given answers. For initial data
[1, 4, "0", "V", null, false, true, 'true', "N"]
with
$result = array_map('strval', $arr);
$result will be
['1', '4', '0', 'V', '', '', '1', 'true', 'N']
This should work even in php4 :)
This will map the array to a new array that utilizes the null ternary operator to either include an original value of the array, or an empty string if that value is null.
$array = array_map(function($v){
return $v ?: '';
},$array);
You can use this instead.
array_map(function($val){return is_null($val)? "" : $val;},$result);
Here's a technique I haven't seen mentioned in the above answers:
$val = strval(#$arr["notfound"]); // will not generate errors and
// defaults to an empty string
This is super handy for $_GET parameter loading to keep things short and readable. Bonus, you can replace strval() with trim() ... or with intval() if you only accept integers.
The default for intval will be 0 if missing or a non-numeric value. The default for strval is "" if empty, null or false.
$val_str = strval(#$_GET['q']);
$val_int = intval(#$_GET['offset']);
See DEMO
Now for an array, you'll still need to loop over every value and set it. But it's very readable, IMO:
$arr = Array (1, 4, "0", "V", null, false, true, 'true', "N");
foreach ($arr as $key=>$value) {
$arr[$key] = strval($value);
}
echo ("['".implode("','", $arr)."']");
Here is the result:
['1','4','0','V','','','1','true','N']
Interesting is that true becomes "1", but 'true' stays a string and that false becomes and empty string "".
Now the same data using $arr[$key] = intval($value); produces this result:
['1','4','0','0','0','0','1','0','0']
foreach($array as $key=>$value)
{
if($value===NULL)
{
$array[$key]="";
}
}
Use this function. This will replace null to empty string in nested array also
$arr = array(
"key1"=>"value1",
"key2"=>null,
"key3"=>array(
"subkey1"=>null,
"subkey2"=>"subvalue2"),
"key4"=>null);
echo json_encode(replace_null_with_empty_string($arr));
function replace_null_with_empty_string($array)
{
foreach ($array as $key => $value)
{
if(is_array($value))
$array[$key] = replace_null_with_empty_string($value);
else
{
if (is_null($value))
$array[$key] = "";
}
}
return $array;
}
Output will be :
{
"key1": "value1",
"key2": "",
"key3": {
"subkey1": "",
"subkey2": "subvalue2"
},
"key4": ""
}
Try online here : https://3v4l.org/7uXTL
This can be solved in one line using:
array_walk($array_json_return,function(&$item){$item=strval($item);});
here $array_json_return is the array.