Changes to array of JSON objects based on other array - php

I have an array of JSON objects that look like this:
{"id":1,"place":2,"pic_name":"aaa.jpg"}
My PHP file receives a simple array like:
["4","3","1","2","5"]
These numbers correspond to the place value in my JSON object. Now I need to compare the place of each element in the secont array with the value of ID in the JSON object and if the match I have to replace the value of PLACE with the element from the array.
I am having problems doing the comparison. Any guidelines? What I come up with:
foreach($ids as $index=>$id) { //the array
$id = (int) $id;
foreach ($obj as $key=>$value) { //the JSON objects
foreach ($value as $k=>$v){
if ($id != '' && array_search($index, array_keys($ids)) == $value[$k]['id']) {
$value[$k]['place'] = $id;
file_put_contents($file, json_encode($ids));
} else { print "nope";}
} } }

That will be:
$array = [
'{"id":1,"place":2,"pic_name":"aaa.jpg"}',
'{"id":2,"place":5,"pic_name":"aab.jpg"}',
'{"id":3,"place":1,"pic_name":"aba.jpg"}',
'{"id":4,"place":3,"pic_name":"baa.jpg"}',
'{"id":5,"place":4,"pic_name":"abb.jpg"}'
];
$places = ["4","3","1","2","5"];
$array = array_map(function($item)
{
return json_decode($item, 1);
}, $array);
foreach($array as $i=>$jsonData)
{
if(false!==($place=array_search($jsonData['id'], $places)))
{
$array[$i]['place'] = $place+1;
}
}
$array = array_map('json_encode', $array);
//var_dump($array);
-with output like:
array(5) {
[0]=>
string(39) "{"id":1,"place":3,"pic_name":"aaa.jpg"}"
[1]=>
string(39) "{"id":2,"place":4,"pic_name":"aab.jpg"}"
[2]=>
string(39) "{"id":3,"place":2,"pic_name":"aba.jpg"}"
[3]=>
string(39) "{"id":4,"place":1,"pic_name":"baa.jpg"}"
[4]=>
string(39) "{"id":5,"place":5,"pic_name":"abb.jpg"}"
}

Related

how to add child array with dynamic key in loop PHP

i have string like this
$string = 'root.1.child1.2.nextnode.3.anothernode.4.var';
exploded by "." and created array like this
$arr = array('root','1','child1','2','nextnode','3','anothernode','3','var');
how i can convert this array to something like this ?
it should be dynamically convert because in some cases nodes in string are in a number different with the sample .
["root"]=>
array(1) {
[1]=>
array(1) {
["child1"]=>
array(1) {
[2]=>
array(1) {
["nextnode"]=>
array(1) {
[3]=>
array(1) {
["anothernode"]=>
array(1) {
[3]=>
array(1) {
[var]=>
NULL
}
}
}
}
}
}
}
}
An example using recursive function.
$array = ['root', '1', 'child1', '2', 'nextnode', '3', 'anothernode', '3', 'var'];
function getNestedArray(array $arr, int $idx = 0) {
if ($idx + 1 <= count($arr)) {
return [$arr[$idx] => getNestedArray($arr, $idx + 1)];
}
return null;
}
$output = getNestedArray($array);
var_dump($output);
This can be quit easily achieved by referencing the output and looping over the exploded array:
$output = [];
$reference = &$output;
foreach ($arr as $el) {
if (is_numeric($el)) {
$el = (int)$el;
}
$reference = [];
$reference[$el] = null;
$reference = &$reference[$el];
}
This also checks whether the element is a number and casts it to an integer if it is. The $output variable will contain the final array.
You can use recursive function
to do though
$flatArray = array('root','1','child1','2','nextnode','3','anothernode','3','var'); // your array
function createNestedArray($flatArray)
{
if( sizeof($flatArray) == 1 ) {
return [ $flatArray[0] => null ]; // for the case that paramter has one member we need to return [ somename => null ]
}
$nestedArray[ $flatArray[0] ] = createNestedArray(array_slice($flatArray, 1)); // otherwise we need to call createNestedArray with rest of array
return $nestedArray;
}
$nestedArray = createNestedArray($flatArray); // the result

PHP Change multidimensional array structure

Hello I've multidimensional array that looks like that:
array(13890) {
[0]=>
array(2) {
["Icd"]=>
array(2) {
["id"]=>
int(111)
["nazwa"]=>
string(6) "DŻUMA"
}
["ProjectIcd"]=>
array(0) {
}
}
[1]=>
array(2) {
["Icd"]=>
array(2) {
["id"]=>
int(566)
["nazwa"]=>
string(7) "ŚWINKA"
}
["ProjectIcd"]=>
array(0) {
}
}
An so on.
I want to change it so it looks something like that:
array(13890) {
[0]=> array(2) {
["id"]=>
int(111)
["text"]=>
string(6) "DŻUMA"
}
How is this possible to do?
I want to add, I want to convert the array to json and feed it to select2 js in ajax.
Will that be a problem or not?
Short solution using array_map function:
// $arr is your initial array
$new_arr = array_map(function($a){
return ['id' => $a['Icd']['id'], 'text' => $a['Icd']['nazwa']];
}, $arr);
So you can simple create a new array and add there the values, which you want based on the old array. Then you convert the array to a json string with the php function json_encode():
$array = array("text"=>$old_array[0]["Icd"]["nazwa"]);
echo json_encode($array);
I hope this is something that you want.
$res = [];
$i = 0;
foreach($array as $arr) {
//get keys
if (count($arr) > 0) {
$keys = array_keys($arr);
// loop through the keys and fetch data of those keys
// put in array
foreach($keys as $key) {
if ($arr[$key]) {
$res[$i]['id'] = $arr[$key]['id'];
$res[$i]['text'] = $arr[$key]['nazwa'];
}
$i++;
}
}
}
print_r($res);
// To change array to json
echo json_encode($res);

Building a multidimensional Array with another Array in PHP

I try to build an array. I don't wanna write something like $array[3][5][8] = []. Because the count of the first Array can change, here it's 3 but it also can be like 9 or 12. Also the values can change, but they are always unique numbers. I hope someone knows a better way. Thank you.
// First Array, which I have. The count and the content can change.
array(3) {
[0]=>
string(1) "3"
[1]=>
string(1) "5"
[2]=>
string(1) "8"
}
// Second Array, thats the goal.
array(1) {
[3]=>
array(1) {
[5]=>
array(1) {
[8]=>
array(0) {
}
}
}
}
This code will solve your problem:
$array = [3,5,8,9]; // your first array
$newArray = null;
foreach ($array as $value) {
if($newArray === null) {
$newArray[$value] = [];
$ref = &$newArray[$value];
}
else {
$ref[$value] = [];
$ref = &$ref[$value];
}
}
$newArray - holds the result you wanted
$array1=array(3,5,8);
$array2=array();
for($i=count($array1);$i>0;$i--){
$temp=array();
$temp[$array1[$i-1]]=$array2;
$array2=$temp;
}
$subject is the reference to the array you are currently in.
$array is the main root array that you obtain in the end.
$input is the input int array.
$subject = $array = [];
foreach($input as $key){
$subject[$key] = []; // create empty array
$subject =& $subject[$key]; // set reference to child
// Now $subject is the innermost array.
// Editing $subject will change the most nested value in $array
}

Removing a JSON record from .json file with PHP

I have a json file looking like this :
[["{\"id\":1474721566304,\"name\":\"GGG\",\"brand\":\"GG\",\"price\":\"3\"}"],["{\"id\":1474721570904,\"name\":\"GGGH\",\"brand\":\"GGH\",\"price\":\"4\"}"],["{\"id\":1474721574188,\"name\":\"GGGH\",\"brand\":\"GGHH\",\"price\":\"5\"}"]]
What I am trying to do is to remove a record from it by it's id. For this purpose I have the following PHP code :
<?php
$string = file_get_contents("products.json");
$json_a = json_decode($string, true); //turning JSON-string into an array containing JSON-strings
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true)); //and here you turning each of the JSON-strings into objects themselves
}
$data= $_GET['data'];
$i=0;
foreach($arr as $element) {
if($data == $element["id"]){
unset($arr[$i]);//removing the product by ID
}
$i++;
}
var_dump($arr);
$arr2 = array();
foreach ($arr as $key) {//trying to make it look like the original json.
array_push($arr2,json_decode($key[0],true));
}
//var_dump($arr2);
echo json_encode($arr2);
?>
What I am getting from this code is :
array(2) { [0]=> array(4) { ["id"]=> float(1474721566304) ["name"]=> string(3) "GGG" ["brand"]=> string(2) "GG" ["price"]=> string(1) "3" } [1]=> array(4) { ["id"]=> float(1474721570904) ["name"]=> string(4) "GGGH" ["brand"]=> string(3) "GGH" ["price"]=> string(1) "4" } }
I am really out of ideas how to make this array look like my original JSON shown first on this post. I tried many different things, but I couldn't make it work. My idea is after removing the record by it's ID to replace the old JSON with the new one that I am trying to construct here.
I am new to php and I'd appreciate any input on my issue.
First of all - your input JSON is wrong:
array (size=3)
0 =>
array (size=1)
0 => string '{"id":1474721566304,"name":"GGG","brand":"GG","price":"3"}' (length=58)
1 =>
array (size=1)
0 => string '{"id":1474721570904,"name":"GGGH","brand":"GGH","price":"4"}' (length=60)
2 =>
array (size=1)
0 => string '{"id":1474721574188,"name":"GGGH","brand":"GGHH","price":"5"}' (length=61)
You don't have 'id' nor 'name', 'GGG' and other keys. You just have one long string. You should remove unnecessary quotation marks. After that your JSON should look like this:
[[{"id":1474721566304,"name":"GGG","brand":"GG","price":"3"}],[{"id":1474721570904,"name":"GGGH","brand":"GGH","price":"4"}],[{"id":1474721574188,"name":"GGGH","brand":"GGHH","price":"5"}]]
And finally, your PHP code can be much shorter:
$json = "[[{\"id\":1474721566304,\"name\":\"GGG\",\"brand\":\"GG\",\"price\":\"3\"}],[{\"id\":1474721570904,\"name\":\"GGGH\",\"brand\":\"GGH\",\"price\":\"4\"}],[{\"id\":1474721574188,\"name\":\"GGGH\",\"brand\":\"GGHH\",\"price\":\"5\"}]]";
$input = json_decode($json, true);
$output = array();
foreach($input as $element) { //you don't need to declare yet another array, just use the one you already have
if($_GET['data'] != $element[0]["id"]){ //and not unset, just add to new array if you want
$output[] = $element; //shorter and faster than array_push()
}
}
echo json_encode($output);
Try this code:
$string = file_get_contents("product.json");
$json_a = json_decode($string, true); //turning JSON-string into an array containing JSON-strings
$arr = array();
foreach ($json_a as $key) {
array_push($arr,json_decode($key[0],true)); //and here you turning each of the JSON-strings into objects themselves
}
$data= 0;
$i=0;
foreach($arr as $element) {
if($data == $element["id"]){
unset($arr[$i]);//removing the product by ID
}
$i++;
}
// print_r($arr);
$arr2 = array();
foreach($arr as $key => $val) {
$arr2[][] = $val;
}
//var_dump($arr2);
echo json_encode($arr2);

Recursive function for checking multidimensional arrays

Really struggling with this. I have a multidimensional array n levels deep. Each 'array level' has information I need to check (category) and also check if it contains any arrays.
I want to return the category ids of all the arrays which have a category and do not contain an array (i.e. the leaves). I can echo output properly, but I am at a loss as how to return the ids in an array (without referencing)
I have tried RecursiveIteratorIterator::LEAVES_ONLY and RecursiveArrayIterator but I don't think they work in my case? (Maybe I am overlooking something)
$array
array(2) {
["1"]=>
string(5) "stuff"
["2"]=>
array(2) {
["category"]=>
string(1) "0"
["1"]=>
array(3) {
[0]=>
array(3) {
["category"]=>
string(1) "1"
["1"]=>
string(5) "stuff"
["2"]=>
string(5) "stuff"
}
[1]=>
array(5) {
["category"]=>
string(1) "2"
["1"]=>
string(5) "stuff"
["2"]=>
string(5) "stuff"
}
[1]=>
array(5) {
["1"]=>
string(5) "stuff"
["32"]=>
string(5) "stuff"
}
}
}
}
My function
public function recurs($array, $cats = [])
{
$array_cat = '';
$has_array = false;
// Check if an id exists in the array
if (array_key_exists('category', $array)) {
$array_cat = $array['category'];
}
// Check if an array exists within the array
foreach ($array as $key => $value) {
if (is_array($value)) {
$has_array = true;
$this->recurs($value, $cats);
}
}
// If a leaf array
if (!$has_array && is_numeric($array_cat)) {
echo "echoing the category here works fine: " . $array_cat . "\n";
return $array_cat;
}
}
Calling it
$cats_array = $this->recurse($array)
Output echoed
echoing the category here works fine: 1
echoing the category here works fine: 2
How do I return the ids in an array to use in the $cats_array variable?
EDIT: The output should match the echo, so I should get an array containing (1, 2) since they are the only arrays with categories and no arrays within them
array(2){
[0]=>
int(1) "1"
[1]=>
int(1) "2"
}
If I understood you correctly this function will do the job:
function getCategories(array $data)
{
if ($subArrays = array_filter($data, 'is_array')) {
return array_reduce(array_map('getCategories', $subArrays), 'array_merge', array());
};
return array_key_exists('category', $data) ? array($data['category']) : array();
}
If the array contains any sub-arrays they will be returned by array_filter and you will enter the if statement. array_map will apply the function recursively to the sub-arrays and array_reduce will merge the results.
If the array doesn't contain any sub-arrays you will not enter the if statement and the function will return an array with the category if it is present.
Note that you might need to use array_unique to return unique categories.
Also for small performance optimization instead of array_key_exists you can use isset($array[$key]) || array_key_exists($key, $array).
Update
If you want to update your function to make it work you have to recursively collect and merge the sub results. In the following example I introduced a new variable for this:
public function recurs($array, $cats = [])
{
$result = [];
$array_cat = '';
$has_array = false;
// Check if an id exists in the array
if (array_key_exists('category', $array)) {
$array_cat = $array['category'];
}
// Check if an array exists within the array
foreach ($array as $key => $value) {
if (is_array($value)) {
$has_array = true;
$result = array_merge($result, $this->recurs($value, $cats));
}
}
// If a leaf array
if (!$has_array && is_numeric($array_cat)) {
echo "echoing the category here works fine: " . $array_cat . "\n";
return [$array_cat];
}
return $result;
}

Categories