I have the following JSON array, I would like to adjust the array to only keep unique name values, meaning id could be across numerous objects, but name must be unique, overall Tim and Jacob can only be listed once.
$data = '
[
{
"name": "Jacob",
"id": 4
},
{
"name": "Jacob",
"id": 3
},
{
"name": "Tim",
"id": 2
},
{
"name": "Brady",
"id": 2
},
{
"name": "Tim",
"id": 1
}
]';
$array = json_decode($data, TRUE);
$array = array_values( array_unique( $array, SORT_REGULAR ) );
$result = json_encode( $array );
The following is what I have currently tried, but it looks at both values in the object, so it leaves them as is.
Result I am looking for:
[
{
"name": "Jacob",
"id": 4
},
{
"name": "Tim",
"id": 2
},
{
"name": "Brady",
"id": 2
}
]
You can write a function which goes through each of the entries in the array and removes them if their name has been seen before.
function array_unique_names($array) {
// Copy our input as a temporary new array
$output = $array;
// Keep track of which names we've seen before
$seen_names = [];
foreach ($output as $key => $value) {
// If we've seen a name before, remove it from our output
if (in_array($value['name'], $seen_names)) {
unset($output[$key]);
}
// Otherwise, keep it but add it to the list of seen names
else {
$seen_names[] = $value['name'];
}
}
// Return a re-indexed array
return array_values($output);
}
$data = // Your JSON input string
$array = json_decode($data, TRUE);
$array = array_unique_names($array);
$result = json_encode($array);
Related
I need to update the property accessories of this JSON
{
id: "1",
name: "TEST",
accessories: [
"1",
"2",
"3"
]
}
How can I add 4 or change 3 to 4 to the accessories array?
//Decode JSON to PHP object
$arrr = json_decode('{
"id": "1",
"name": "TEST",
"accessories": [
1,
2,
3
]
}');
$old_value = 3; // The value you want to change
$new_value1 = 4; // The value you want to change it to
$new_value2 = 100; // A new value you want to insert into the array
$array_key = array_search($old_value, $arrr->accessories); // Get array key of old value
$arrr->accessories[$array_key] = $new_value1; // Update array with value
$arrr->accessories[] = $new_value2; // Add extra value to array
echo json_encode($arrr); // Re-encode and print results
// Output: {"id":"1","name":"TEST","accessories":[1,2,4,100]}
You can use array_map as approach:
<?php
$json = json_decode('{
"id": "1",
"name": "TEST",
"accessories": [
1,
2,
3
]
}', true);
$json['accessories'] = array_map(
function($el) {
return $el == 3 ? 4 : $el;
},
$json['accessories']
);
print_r($json);
You can test the solution on PHPize.online
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');
I have an array which look like this :
Result 1:
{
"error_code": 0,
"error_message": "",
"return_data": {
"items": [
{
"id": 462,
"users": "1,36,38"
},
{
"id": 462,
"users": "1,4"
},...... //same for 20 result
]
}
}
I want the users to convert to an array,and separate by the comma,so the whole result will look like this :
The result I want:
{
"error_code": 0,
"error_message": "",
"return_data": {
"items": [
{
"id": 462,
"users": [
{
"user_id": 1
},
{
"user_id": 36
},
{
"user_id": 38
}
],
}.. //other result
]
}
}
Here is what I try :
$res = "array the get the Result 1";
$items = //"I get the items array"
foreach ($items as $key => $item) {
$usersArray = array(); //create a new Array
//spilt the string to array separate with ","
$usersIdArray = explode(',', $items['users']);
//assign the "user_id" key to each value
foreach ($userIdArray as $key => $user) {
$usersArray['user_id'] = $user;
}
//assign the result back to $res
$res['return_data']['items']['users'] = $usersArray;
}
After I assign the array to $res with this line of code $res['return_data']['items']['users'] = $usersArray; ,my result become like below,I state the problem inside the code :
{
"error_code": 0,
"error_message": "",
"return_data": {
"items": {
"0":{ <-- // here suddenly appear a number for each result
"id": 462,
"users": "1,36,38" //here nothing change (I want the array appear here)
},
"1":{
"id": 462,
"users": "1,36,38"
},
"2":{
"id": 462,
"users": "1,36,38"
},
"users": { //the array appear here but not the position I want..and it only appears 1 time.
"user_id": "38"
}
}
}
}
So my question is,how can I convert a String in an array to an array,assign value to the key,and make it inside the array?
Somebody please help..Thanks
Like the comments above, you could have done it the first time so you wouldn't need another structure conversion, but anyway, your code is already there a bit, its just you need to create another nesting since you want another level:
So you need another level here:
"users": [
{
"user_id": 1
},
{
"user_id": 36
},
{
"user_id": 38
}
],
So in the code, just add []. This translates into:
foreach ($items as $key => $item) {
$usersArray['id'] = $item['id'];
$usersArray['users'] = array(); //create a new Array
$usersIdArray = explode(',', $item['users']);
foreach ($usersIdArray as $key => $user) {
$usersArray['users'][] = array('user_id' => $user); // push each batch of key pair "user_id" key and value "each exploded id"
// another level ^
}
$res['return_data']['items'][] = $usersArray;
}
Here's the fiddle to check it out.
I am trying to create a json object from the data that I get from Ninja Forms that would look like this:
{
"title": "Contact Me",
"fields": [
{
"label": "Name",
"type": "textbox",
"required": "1"
},
{
"label": "Email",
"type": "email",
"required": "1"
}
]
}
I am trying to do so, like this:
$settings = ['label', 'type', 'required'];
$formTitle = Ninja_Forms()->form( 1 )->get()->get_setting('title');
$formFields = Ninja_Forms()->form(1)->get_fields();
$data = ['title' => $formTitle];
foreach ($formFields as $formField) {
$key = $formField->get_setting('key');
foreach ($settings as $setting) {
$data['fields'][$key][][$setting] = $formField->get_setting($setting);
}
}
return $data;
But, the result of that looks like this:
{
"title": "Contact Me",
"fields": {
"name": [
{ "label": "Name" },
{ "type": "textbox" },
{ "required": "1"}
],
"email": [
{ "label": "Email" },
{ "type": "email" },
{ "required": "1" }
],
How can I do this, so that the result looks like the one I have shown above?
I have also tried like this:
foreach ($settings as $setting) {
$data['fields'][] = $formField->get_setting($setting);
}
But, that gave me this kind of result:
{
"title": "Contact Me",
"fields": [
"Name",
"textbox",
"1",
"Email",
"email",
"1",
"Message",
"textarea",
"1",
"Submit",
"submit",
null
]
}
This gave me the wanted result:
foreach ($formFields as $formField) {
$key = $formField->get_setting('key');
foreach ($settings as $setting) {
$object[$setting] = $formField->get_setting($setting);
}
$data['fields'][] = $object;
}
return $data;
One way to look at this is to count the dimensions of the data. In your desired format, the deepest item is:
{ "fields": [ { "label": "Name"
So you have object -> array -> object.
If we indent each array in your code, we have:
$data // outermost array
['fields']
[$key]
[] // innermost array
[$setting] = $value; // key in innermost array
Or if we were to declare it with just one value:
$data = array(
'field' => array(
$key => array(
0 => array(
$setting => $value
)
)
)
);
So you have 4 levels of array, instead of 3.
Comparing to the JSON, taking an array with numeric keys as "array" and one with non-numeric keys as "object", the pattern is object -> object -> array -> object.
So it's the [$key] we need to eliminate, because it's creating an extra object dimension.
But we don't want to increment the key at [] for each item either, so we need to either make our value in advance...
foreach ($settings as $setting) {
$object[$setting] = $formField->get_setting($setting);
}
$data['fields'][] = $object;
...or choose our key in advance:
$i++;
foreach ($settings as $setting) {
$data['fields'][$i] = $formField->get_setting($setting);
}
I have a multidimensional JSON array that I need to add values to. The JSON array is external and I cannot change its format.
I've tried doing 3 foreach loops, but then I get myself lost in how to add data to the array. I keep catching myself stuck in a loop.
Here's the JSON:
{
"positions": [{
"report_at": "2017-03-13 20:04:10",
"elev": "0",
"dir": "0",
"id": "1"
}, {
"report_at": "2017-03-07 00:28:14",
"elev": "1240",
"dir": "89",
"id": "2"
}]
}
I have unique data I need to add to id 1, and another set of unique data I need to add to id 2.
Here's what I've tried:
$data = json_decode( $result, true );
foreach ( $data as $d ) {
foreach ( $d as $key => $data ) {
if ( $data['id'] == '1' ) {
$data[] = array(
"online_status" => "1",
"name" => "Test User",
);
} elseif ( $data['id'] == '2' ) {
$data[] = array(
"online_status" => "0",
"name" => "Another User",
);
}
}
}
$json = json_encode( $data );
echo $json;
I think once I can get this figured out, then I can pull data from MySQL, build small arrays based off that data, then add those to these sub-arrays where the ID matches the SQL ID. Any help is appreciated.
JSON seems to be just object with "positions" field which is array, you need to modify.
$data = json_decode($json, TRUE);
foreach ($data['positions'] as &$userInfo) {
if ($userInfo['id'] == 1) {
$userInfo['online_status'] = 'offline';
$userInfo['name'] = 'Test user';
}
}
echo json_encode($data);
Notice "&" sign in foreach, which means, that modification made within foreach, will be stored to original array.
Also you should be aware of key=>value naming in foreach. Your second foreach creates variable named $data, which means, that you are loosing pointer to original array!
Use the following approach:
$data = json_decode($result, true);
foreach ($data['positions'] as &$item) {
if ($item['id'] == "1") {
$item = array_merge($item, ["online_status" => "1", "name" => "Test User"]);
} else if ($item['id'] == "2") {
$item = array_merge($item, ["online_status" => "0", "name" => "Another User"]);
}
}
$json = json_encode($data, JSON_PRETTY_PRINT);
echo $json;
The output:
{
"positions": [
{
"report_at": "2017-03-13 20:04:10",
"elev": "0",
"dir": "0",
"id": "1",
"online_status": "1",
"name": "Test User"
},
{
"report_at": "2017-03-07 00:28:14",
"elev": "1240",
"dir": "89",
"id": "2",
"online_status": "0",
"name": "Another User"
}
]
}