Merge two JSON arrays and then sort them - php

How would I merge both JSON arrays and then sort the value of ID so that the result displays the highest number to the lowest number?
For example, my desired output from the script below would be:
1 - Jimbo
2 - Bob
6 - Luke
12 - Chris
16 - Jonas
36 - Sam
Here's my JSON arrays:
$json1 ='
{
"error": "trueee",
"info": {
"collections": [{
"ID": "1"
"Name": "Jimbo"
}, {
"ID": "36"
"Name": "Sam"
}, {
"ID": "2",
"Name": "Bob"
}]
}
}
';
$json2 ='
{
"error": "trueee",
"info": {
"collections": [{
"ID": "12"
"Name": "Chris"
}, {
"ID": "6"
"Name": "Luke"
}, {
"ID": "16"
"Name": "Jonas"
}]
}
}
';

You need to merge the arrays from the json string. First json decode for getting the arr with associative array than get the columns of ID using array_column, after that you need to merge the two array and finally sort them.
Online Check and a Long Conversation
$json1 ='
{
"error": "trueee",
"info": {
"collections": [{
"ID": "1"
}, {
"ID": "36"
}, {
"ID": "2"
}]
}
}
';
$json2 ='
{
"error": "trueee",
"info": {
"collections": [{
"ID": "12"
}, {
"ID": "6"
}, {
"ID": "16"
}]
}
}
';
$arr1 = json_decode($json1, true);
$arr2 = json_decode($json2, true);
$arr1 = array_column($arr1['info']['collections'], "ID");
$arr2 = array_column($arr2['info']['collections'], "ID");
$arr = array_merge($arr1, $arr2);
sort($arr);
echo '<pre>';
print_r($arr);
Result:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 12
[4] => 16
[5] => 36
)

Related

PHP: remove from array of objects all duplicates by key, except first one

I have the following associative array of objects:
[
0: {
"score": "value2",
"number": "1",
"finalScore": "-1"
},
1: {
"score": "value3",
"number": "2",
"finalScore": "5"
},
2: {
"score": "value4",
"number": "2",
"finalScore": "5"
},
3: {
"score": "value5",
"number": "3",
"finalScore": "-1"
}
]
Please, have in mind the following format is the prettified JSON string on the browser, after returning it from PHP through an echo json_encode($result)
I need to filter it based on the number property value, in order to remove all duplicates with the same value for the number property except the first one. This means that if two or more objects share the same value for number, only the first one should remain.
Given this explanation, the filtered array from the example above would result on:
[
0: {
"score": "value2",
"number": "1",
"finalScore": "-1"
},
1: {
"score": "value3",
"number": "2",
"finalScore": "5"
},
2: {
"score": "value5",
"number": "3",
"finalScore": "-1"
}
]
I have made several attempts, the closest I've been is this funcion:
function array_iunique($array) {
$lowered = array_map('strtolower', $array);
return array_intersect_key($array, array_unique($lowered));
}
Sounds pretty straight forward to me: you iterate over the input array and accept the elements only if the output does not yet contain such a candidate...
<?php
$input = json_decode(<<<EOT
[
{
"score": "value2",
"number": "1",
"finalScore": "-1"
}, {
"score": "value3",
"number": "2",
"finalScore": "5"
}, {
"score": "value4",
"number": "2",
"finalScore": "5"
}, {
"score": "value5",
"number": "3",
"finalScore": "-1"
}
]
EOT);
$output = [];
array_walk($input, function ($entry) use (&$output) {
if (!array_key_exists($entry->number, $output)) {
$output[$entry->number] = $entry;
}
});
print_r(array_values($output));
The output obviously is:
Array
(
[0] => stdClass Object
(
[score] => value2
[number] => 1
[finalScore] => -1
)
[1] => stdClass Object
(
[score] => value3
[number] => 2
[finalScore] => 5
)
[2] => stdClass Object
(
[score] => value5
[number] => 3
[finalScore] => -1
)
)
Simple approache:
Firstly, convert data from json format to array of scores using json_decode with second args true.
Secondly, create three variable one for output $scores_filtered, second to keep track only unique numbers and $index to keep the order ascending of $scores_filtered array.
Thirdly, iterate over the array of score and check if the number first time occures (meaning doesn't exist in array $unique_numbers) if So, store it in $unique_numbers. get that score and store in $scores_filtered array.
$json = '[{
"score": "value2",
"number": "1",
"finalScore": "-1"
},{
"score": "value3",
"number": "2",
"finalScore": "5"
},{
"score": "value4",
"number": "2",
"finalScore": "5"
},{
"score": "value5",
"number": "3",
"finalScore": "-1"
}
]';
$scores = json_decode($json, true);
$scores_filtered = [];
$unique_numbers = [];
$index = 0;
for($i = 0; $i < count($scores); $i++) {
$score = $scores[$i];
if(!in_array($score['number'], $unique_numbers)){
$unique_numbers[] = $score['number'];
$scores_filtered[$index]["score"] = $score["score"];
$scores_filtered[$index]["number"] = $score["number"];
$scores_filtered[$index]["finalScore"] = $score["finalScore"];
$index += 1;
}
}
Output:
echo "<pre>";
print_r(json_encode($scores_filtered, JSON_PRETTY_PRINT));
/*
[
{
"score": "value2",
"number": "1",
"finalScore": "-1"
},
{
"score": "value3",
"number": "2",
"finalScore": "5"
},
{
"score": "value5",
"number": "3",
"finalScore": "-1"
}
]
*/

PHP: Convert Object to Associative Array with Object Property as Key

In PHP, I'd like to convert an array of objects like the following to a PHP array, using one of the properties as the associative array keys.
[
{ "id": 2, "name": "Suzy" },
{ "id": 3, "name": "Joe" },
{ "id": 4, "name": "Sara" }
]
like this...
[
2 => "Suzy",
3 => "Joe",
4 => "Sara"
]
I can't use array_map because you can't set the keys from my understanding, but I'm wondering if there's a one-liner way to do it without a foreach loop.
To be clear, I want to maintain the keys in the output array, not puts the original keys inside the new array values like they do here: PHP's array_map including keys
It appears by "object" you mean a JSON object. Given that, you can use array_column() to pull out a single column from each row, and then array_combine() to use one column for the keys and another for the values:
$json = '[
{ "id": 2, "name": "Suzy" },
{ "id": 3, "name": "Joe" },
{ "id": 4, "name": "Sara" }
]';
$array = json_decode($json, true);
$out = array_combine(array_column($array, 'id'), array_column($array, 'name'));
print_r($out);
Yields:
Array
(
[2] => Suzy
[3] => Joe
[4] => Sara
)
2 liners and has a foreach though.
<?php
$json = '[
{ "id": 2, "name": "Suzy" },
{ "id": 3, "name": "Joe" },
{ "id": 4, "name": "Sara" }
]';
$new_array = [];
foreach(json_decode($json,true) as $each_object) $new_array[$each_object['id']] = $each_object['name'];
print_r($new_array);
$json = '[
{ "id": 2, "name": "Suzy" },
{ "id": 3, "name": "Joe" },
{ "id": 4, "name": "Sara" }
]';
$array = json_decode($json, true);
$result = array_column($array, 'name', 'id');

Rewrite json in loop

I have an array, which i wrote like a table for more reability.
[{
"id": "1",
"title": "boune",
"value": "3"
}, {
"id": "2",
"title": "check",
"value": "4"
}, {
"id": "3",
"title": "boune",
"value": "5"
}]
As the result of what i want to see is this json, where 'value' of identical 'titles' united inside [] brackets. I am very newbie in php. I undestand that i need for loop to sort query result, but can`t heck...Cant even put my mind to it...
[{
"id":"1",
"title": "boune",
"value": [3, 5]
}]
<?php
$json = '[{"id":"1","title":"boune","value":"3"},{"id":"2","title":"check","value":"4"},{"id":"3","title":"boune","value":"5"}]';
$json_data = json_decode($json,true);
function accumulateValuesByTitle($json_data){
$hash = [];
foreach($json_data as $each_record){
if(isset($hash[$each_record['title']])){
$hash[$each_record['title']]['value'][] = $each_record['value'];
if($hash[$each_record['title']]['id'] > $each_record['id']){
$hash[$each_record['title']]['id'] = $each_record['id'];
}
}else{
$hash[$each_record['title']] = $each_record;
$hash[$each_record['title']]['value'] = [$hash[$each_record['title']]['value']];
}
}
return array_values($hash);
}
$modified_data = accumulateValuesByTitle($json_data);
echo json_encode($modified_data);

Merge JSON array values using PHP

I have two JSON arrays with some values. I need to merge those values in a format using PHP. Here is the array format and the output format that I needed:
Array 1:
{
"data": {
"1": {
"id": 1,
"name": "red"
},
"25": {
"id": 3,
"name": "green"
}
}
}
Array 2:
{
"data": {
"10": {
"id": 14,
"name": "blue"
},
"22": {
"id": 5,
"name": "white"
}
}
}
Expected Result after merge:
{
"data": {
"1": {
"id": 1,
"name": "red"
},
"25": {
"id": 3,
"name": "green"
}
},
"10": {
"id": 14,
"name": "blue"
},
"22": {
"id": 5,
"name": "white"
}
}
Thank you.
Try this code
<?php
$json1 = '{
"data": {
"1": {
"id": 1,
"name": "red"
},
"25": {
"id": 3,
"name": "green"
}
}
}';
$json2 = '{
"data": {
"10": {
"id": 14,
"name": "blue"
},
"22": {
"id": 5,
"name": "white"
}
}
}';
// Decode json into array
$jArray1 = json_decode($json1, true);
$jArray2 = json_decode($json2, true);
// Merging array
$merge['data'] = $jArray1['data'] + $jArray2['data'];
// Encoding array to json
$mergedJson = json_encode($merge);
print_r( $mergedJson );
?>
$de_json = json_decode('{
"data": {
"1": {
"id": 1,
"name": "red"
},
"25": {
"id": 3,
"name": "green"
}
}}', True);
echo '<pre>';print_r($de_json);
You will get this output
Array
(
[data] => Array
(
[1] => Array
(
[id] => 1
[name] => red
)
[25] => Array
(
[id] => 3
[name] => green
)
)
)
the convert other two json array to php array and
use array_merge() to get the merged array.

PHP array to Json tree format

I want to tranform an php array into an json string to use with JavaScript InfoVis Toolkit formart.
the objective:
InfoVis Demo Tree
Json specification format:
InfoVis-loading and serving JSON data
I have this php array: $my_array :
Array
(
[item_1] => Array
(
[id] => item_1_ID
[name] => item_1_NAME
[data] => item_1_DATA
[children] => Array
(
[door] => Array
(
[id] => door_ID
[name] => door_NAME
[data] => door_DATA
[children] => Array
(
[mozart] => Array
(
[id] => mozart_ID
[name] => mozart_NAME
[data] => mozart_DATA
[children] => Array
(
[grass] => Array
(
[id] => grass_ID
[name] => grass_NAME
[data] => yes
)
[green] => Array
(
[id] => green_ID
[name] => green_NAME
[data] => no
)
[human] => Array
(
[id] => human_ID
[name] => human_NAME
[data] => human_DATA
[children] => Array
(
[blue] => Array
(
[id] => blue_ID
[name] => blue_NAME
[data] => blue_DATA
[children] => Array
(
[movie] => Array
(
[id] => movie_ID
[name] => movie_NAME
[data] => yes
)
)
)
)
)
)
)
)
)
[beat] => Array
(
[id] => beat_ID
[name] => beat_NAME
[data] => yes
)
[music] => Array
(
[id] => music_ID
[name] => music_NAME
[data] => no
)
)
)
)
now if I json_encode($my_array);
{
"item_1": {
"id": "item_1_ID",
"name": "item_1_NAME",
"data": "item_1_DATA",
"children": {
"door": {
"id": "door_ID",
"name": "door_NAME",
"data": "door_DATA",
"children": {
"mozart": {
"id": "mozart_ID",
"name": "mozart_NAME",
"data": "mozart_DATA",
"children": {
"grass": {
"id": "grass_ID",
"name": "grass_NAME",
"data": "yes"
},
"green": {
"id": "green_ID",
"name": "green_NAME",
"data": "no"
},
"human": {
"id": "human_ID",
"name": "human_NAME",
"data": "human_DATA",
"children": {
"blue": {
"id": "blue_ID",
"name": "blue_NAME",
"data": "blue_DATA",
"children": {
"movie": {
"id": "movie_ID",
"name": "movie_NAME",
"data": "yes"
}
}
}
}
}
}
}
}
},
"beat": {
"id": "beat_ID",
"name": "beat_NAME",
"data": "yes"
},
"music": {
"id": "music_ID",
"name": "music_NAME",
"data": "no"
}
}
}
}
But to InfoVis the current json output (json_encode($my_array)) has 3 problems:
is not using [ ]
the 'children' arrays have the key names
arrays items is with their key names -> example: "item_1": { ....
let me point the problem so maybe you can help with an function to transform this json string:
see this slice of json_encode($my_array) output:
{
"item_1": {
"id": "item_1_ID",
"name": "item_1_NAME",
"data": "item_1_DATA",
"children": {
"door": {
"id": "door_ID",
1. problem 1:
{
"item_1": {
we have to remove those keys like: "item_1":
2. problem 2:
"children": {
"door": {
"id": "door_ID",
the correct code for this should be:
"children": [
{
"id": "door_ID",......
"door": was removed... because it`s a key
"children": { => becomes" "children": [
An working example of 'children':
"children": [
{
"id": "grass_ID",
"name": "grass_NAME",
"data": "yes"
},
{
"id": "green_ID",
"name": "green_NAME",
"data": "no"
}
]
to clarify an complete example of WORKING Json InfoVis format:
json = {
id: "node02",
name: "0.2",
children: [{
id: "node13",
name: "1.3",
children: [{
id: "node24",
name: "2.4"
}, {
id: "node222",
name: "2.22"
}]
}, {
id: "node125",
name: "1.25",
children: [{
id: "node226",
name: "2.26"
}, {
id: "node237",
name: "2.37"
}, {
id: "node258",
name: "2.58"
}]
}, {
id: "node165",
name: "1.65",
children: [{
id: "node266",
name: "2.66"
}, {
id: "node283",
name: "2.83"
}, {
id: "node2104",
name: "2.104"
}, {
id: "node2109",
name: "2.109"
}, {
id: "node2125",
name: "2.125"
}]
}, {
id: "node1130",
name: "1.130",
children: [{
id: "node2131",
name: "2.131"
}, {
id: "node2138",
name: "2.138"
}]
}]
};
is it clear to understand?
Hope anyone can help me.. I'm working on this for days!
thank you.
Try this quickie conversion function
function fixit($yourArray) {
$myArray = array();
foreach ($yourArray as $itemKey => $itemObj) {
$item = array();
foreach ($itemObj as $key => $value) {
if (strtolower($key) == 'children') {
$item[$key] = fixit($value);
} else {
$item[$key] = $value;
}
}
$myArray[] = $item;
}
return $myArray;
}
$fixed = fixit($my_array);
$json = json_encode($fixed);
PHP doesn't differentiate between arrays (numeric keys) and associative arrays (string keys). They're all just Arrays. Javascript DOES differentiate. Since you're using string keys, they HAVE to be done as objects ({}) in JS.
You can't tell json_encode to ignore the keys in an array (e.g. your 'children' sub-arrays). That'd mean the produced JSON is NOT the same as the original PHP structure - you've now changed key names.
You'd have to process your array and convert all those children sub-array keys to numbers:
grass -> 0
green -> 1
etc...
so that json-encode could see that it's a numerically keyed PHP array, meaning it'll produce an actual javavscript array ([]), and not an object ({}).
The alternative is writing your own JSON-encoder to do this on-the-fly for you.
This is documented behaviour. An associative array will produce an object literal when JSON stringified with json_encode. Update your original array structure to represent the outcome you want, instead of mangling the produced JSON representation, or wrap your own solution around json_encode for each object.
Edit: attempting a cleanup operation
The code
$original = <your original data-array>; // assumed, I reversed your encoded JSON as test data
// Start by stripping out the associative keys for level 1
$clean = array_values($original);
// Then recursively descend array, and do the same for every children-property encountered
function &recursiveChildKeysCleaner(&$arr) {
// If $arr contains 'children'...
if (array_key_exists('children', $arr)) {
/// ...strip out associative keys
$arr['children'] = array_values($arr['children']);
// ...and descend each child
foreach ($arr['children'] as &$child) {
recursiveChildKeysCleaner($child);
}
}
return $arr;
}
foreach ($clean as &$item) {
recursiveChildKeysCleaner($item);
}
unset($item);
echo json_encode($clean);
Output
[{
"id": "item_1_ID",
"name": "item_1_NAME",
"data": "item_1_DATA",
"children": [{
"id": "door_ID",
"name": "door_NAME",
"data": "door_DATA",
"children": [{
"id": "mozart_ID",
"name": "mozart_NAME",
"data": "mozart_DATA",
"children": [{
"id": "grass_ID",
"name": "grass_NAME",
"data": "yes"
},
{
"id": "green_ID",
"name": "green_NAME",
"data": "no"
},
{
"id": "human_ID",
"name": "human_NAME",
"data": "human_DATA",
"children": [{
"id": "blue_ID",
"name": "blue_NAME",
"data": "blue_DATA",
"children": [{
"id": "movie_ID",
"name": "movie_NAME",
"data": "yes"
}]
}]
}]
}]
},
{
"id": "beat_ID",
"name": "beat_NAME",
"data": "yes"
},
{
"id": "music_ID",
"name": "music_NAME",
"data": "no"
}]
}]

Categories