how to match a key value pair in a JSON - php

[
{"category":["30","32","33"],"type":"30 days","price":"100","ID":"0"},
{"category":["34","37","47"],"type":"30 days","price":"200","ID":1},
{"category":["46"],"type":"40 days","price":"100","ID":2}
]
in the above JSON, how to get all the category which has type: 30days.
Expected Output as.
$categories = array{0=>30,1=>32,2=>33,3=>34,4=>37,4=>47}

You can use array_walk as
$json = '[
{"category":["30","32","33"],"type":"30 days","price":"100","ID":"0"},
{"category":["34","37","47"],"type":"30 days","price":"200","ID":1},
{"category":["46"],"type":"40 days","price":"100","ID":2}
]';
$arr = json_decode($json,true);
$categories = array();
array_walk($arr,function($v,$k)use(&$categories,$arr){
if($v['type'] == "30 days"){
$categories = array_merge($categories,$v['category']);
}
});

Use this:
$json = '[
{"category":["30","32","33"],"type":"30 days","price":"100","ID":"0"},
{"category":["34","37","47"],"type":"30 days","price":"200","ID":1},
{"category":["46"],"type":"40 days","price":"100","ID":2}
]';
$a = json_decode($json,true);
$categories = array();
foreach($a as $ar){
if($ar['type'] == '30 days'){
$categories = array_merge($categories,$ar['category']);
}
}
print_r($categories);
Output:
Array ( [0] => 30 [1] => 32 [2] => 33 [3] => 34 [4] => 37 [5] => 47 )
http://sandbox.onlinephpfunctions.com/code/ea84f8a5baf5c231b4e9427b3b79f16bbc075401

Just chain a bunch of transformation functions together:
$data =<<<JSON
[
{"category":["30","32","33"],"type":"30 days","price":"100","ID":"0"},
{"category":["34","37","47"],"type":"30 days","price":"200","ID":1},
{"category":["46"],"type":"40 days","price":"100","ID":2}
]
JSON;
$data = json_decode($data, true);
$x = call_user_func_array('array_merge', array_column(array_filter($data, function($row) {
return $row['type'] == '30 days';
}), 'category'));
print_r($x);
See also: array_filter() array_column() call_user_func_array()

Related

How to get the ages that are greater than 50 in php

Need to get all the age keys and count the number of them greater than 50. Given data
$data = '{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}';
Output should be 2 as there are 2 ages greater than 50
This is what I am trying
$array = json_decode($data, true);
$strArray = explode(',', $array['data']);
$temp1 = array();
for($i=0; $i < count($strArray); $i++){
$key_value = explode('=', $strArray[$i]);
$temp1[$i][$key_value[0]] = $key_value[1];
}
print "<pre>";
print_r($temp1);
print "</pre>";
Output is coming as
Array
(
[0] => Array
(
[key] => IAfpK
)
[1] => Array
(
[ age] => 58
)
[2] => Array
(
[ key] => WNVdi
)
[3] => Array
(
[ age] => 64
)
[4] => Array
(
[ key] => jp9zt
)
[5] => Array
(
[ age] => 47
)
)
Need to get all the ages in an array to compare.
If your data is truly semi-structured like that and isn’t too massive, and you want to keep the keys, I think this is a good case for array_shift to reduce the array until it is exhausted:
$data = '{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}';
$array = json_decode($data, true);
$strArray = explode(',', $array['data']);
$clean = [];
while(count($strArray) >= 2){
$key = explode('=', array_shift($strArray))[1];
$age = explode('=', array_shift($strArray))[1];
$clean[$key] = (int)$age;
}
var_dump($clean);
Demo: https://3v4l.org/RIF2q
You should hopefully be able to add whatever logic you need to test ages then.
Short and simple. Hope this will work for you,
$output = [];
$data = '{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}';
$array = json_decode($data, true);
foreach (explode(',',$array['data']) as $key => $value)
{
if(str_contains($value,'age'))
{
$age = explode('=',$value);
if($age[1] > 50)
{
array_push($output, $age[1]);
}
}
}
print_r($output);
An effective way to achieve this since your data is strangely formatted would be to use regex. For some reason, the ?: non capturing group is still being captured so all of the ages will be in the second capture group of the match array - you can play to optimise that.
Once you have all your ages in an array, a simple array_filter for ages larger than 50 is more than enough. You can see a live working example on 3v4l.org.
$data = '{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}';
preg_match_all('/(?:age=)([0-9]+)/', json_decode($data)->data, $matches, PREG_PATTERN_ORDER);
// Only continue if we found any ages in the string
if (array_key_exists(1, $matches))
{
// 58, 64
$greaterThan50 = array_filter($matches[1], fn($age) => intval($age) > 50);
}
Ofc, if you then need the corresponding key, you will need to do more magic.
If you're using less than PHP 7.4, arrow functions are not supported. You can instead replace $greaterThan50 assignment to:
$greaterThan50 = array_filter($matches[1], function($age) {
return intval($age) > 50;
});
See it working live on 34vl.org
Based on your logic, You can do it as follows :
<?php
$data = '{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}';
$array = json_decode($data, true);
$strArray = explode(',', $array['data']);
$keys = array();
$ages = array();
for($i=0; $i < count($strArray); $i++){
$key_value = explode('=', $strArray[$i]);
if ((int)$key_value[1] > 0 ) {
array_push($ages, $key_value[1]);
} else {
array_push($keys, $key_value[1]);
}
}
$result = array_combine($keys, $ages);
$result = array_filter($result, function($age) {
return intval($age) > 50;
});
print "<pre>";
print_r($result);
print "</pre>";

Convert flat array of string into associative array

I want to convert this array of string;
$arList = ["the","quick","brown","fox"];
into this format.
[
"the" => [
"quick" => [
"brown" => []
]
]
]
Sorry for not posting some code.
here is what I tried,
<?php
$arList = ["the","quick","brown","fox"];
$newList = [];
$pointer = $newList;
foreach($arList as $item) {
$pointer[$item] = [];
$pointer = &$newList[$item];
}
echo "<pre>";
print_r($newList);
echo "</pre>";
I found a solution from the net using the following code;
$result = array_reduce(array_reverse($arList), function($prevArray, $key){
return $prevArray ? [$key => $prevArray] : [$key];
}, null);

Re-index numeric nested arrays keys

Here is my array:
$arr = [
1 => [
2 => "something",
3 => "something else"
],
2 => "foo br"
];
I need to restart all keys and start all of them from 0. Based on some researches, I figured out I have to use array_values() function. But it just makes the keys of outer array re-index, See.
How can I apply it on the all keys of array? (even nested ones)
You can use array_values + recursively calling custom function:
function arrayValuesRecursive($array) {
$array = array_values($array);
$countValues = count($array);
for ($i = 0; $i < $countValues; $i++ ) {
$subElement = $array[$i];
if (is_array($subElement)) {
$array[$i] = arrayValuesRecursive($subElement);
}
}
return $array;
}
$restructuredArray = arrayValuesRecursive($array);
You can implement it using recursion like this:
function reIndex($arr) {
$arr = array_values($arr);
foreach ($arr as $k => $v) {
if (is_array($v)) {
$arr[$k] = reIndex($v);
}
}
return $arr;
}
$arr = reIndex($arr);
Hi checkout following code
<?php
$arr = [
1 => [
2 => "something",
3 => "something else"
],
2 => "foo br"
];
$reIndexedArray = array();
foreach($arr as $arrItr){
$reIndexedArray[] = count($arrItr) > 1 ? array_values($arrItr) : $arrItr;
}
print_r($reIndexedArray);
?>
output is
Array
(
[0] => Array
(
[0] => something
[1] => something else
)
[1] => foo br
)

How to convert array to associative array?

This is my array format:
$data=["error.png","invoice_1.pdf","invoice2.png"];
But I want to this format:
$data=[{"file":"error.png"},{"file":"invoice_1.pdf"},{"file":"invoice2.png"}]
Thank you.
You should create a new array.
And loop through your existing array.
Its every element will be an array with a value from your array as value.
And key as the string file.
$arr = array();
foreach ($data as $elem) {
$arr[] = array('file' => $elem);
}
Try debugging if you get the correct array:
echo '<pre>';
print_r($arr);
echo '</pre>';
Lastly,
echo json_encode($arr);
exit;
Hope it works for you.
Use
$data = array_map(
function ($item) {
return array('file' => $item);
},
$data
);
to embed the values into arrays, or
$data = array_map(
function ($item) {
$x = new stdClass();
$x->file = $item;
return $x;
},
$data
);
to embed them into objects.
Or, better, use your own class instead of stdClass() and pass $item as argument to its constructor
$data = array_map(
function ($item) {
return new MyClass($item);
},
$data
);
$data = ["error.png", "invoice_1.pdf", "invoice2.png"];
$newarray = array();
foreach ($data as $val){
array_push($newarray, array("file" => $val));
}
print_r($newarray); //Array ( [0] => Array ( [file] => error.png ) [1] => Array ( [file] => invoice_1.pdf ) [2] => Array ( [file] => invoice2.png ) )
echo json_encode($newarray); // [{"file":"error.png"},{"file":"invoice_1.pdf"},{"file":"invoice2.png"}]
exit;
Just try this logic
$data = '["error.png","invoice_1.pdf","invoice2.png"]';
$data = json_decode($data);
$data = array_filter($data, function(&$item){return ($item = array('file' => $item));});
$data = json_encode($data);

how to detect a duplicate element between two json object in php

i trying to detect a different element between 2 json objects like this;
//Json1
[
{"file":"arrowssss.png"},
{"file":"arrows.png"},
{"file":"logo.png"}
]
//Json1
[
{"file":"arrows.png"},
{"file":"logo.png"}
]
I need return Arrowsss.png.
Any Suggestion?
Try
function flatten(array $array) {
$return = array();
array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
return $return;
}
$json1 = '[{"file":"arrowssss.png"},
{"file":"arrows.png"},
{"file":"logo.png"}]';
$json2 = '[{"file":"arrows.png"},
{"file":"logo.png"}]';
$array1 = flatten(json_decode($json1,true));
$array2 = flatten(json_decode($json2,true));
print_r(array_diff($array1,$array2));
Results :-
Array ( [0] => arrowssss.png )
$json1='[
{"file":"arrowssss.png"},
{"file":"arrows.png"},
{"file":"logo.png"}
]';
$json2 = '[
{"file":"arrows.png"},
{"file":"logo.png"}
]';
function getFile($key)
{
return isset($key['file']) ? $key['file'] : null;
}
$diff = array_diff(array_map('getFile', json_decode($json1, true)), array_map('getFile', json_decode($json2, true)));
print_r($diff);
Result:-
Array ( [0] => arrowssss.png )

Categories