Search jsonarray for multiple values dynamically using php - php

i have a json array
[
{
"id":1.25,
"name":"rose",
"Number":15,
"SSN":[
12345,
3455
]
},
{
"id":1.15,
"name":"orchid",
"Number":7,
"SSN":[
12345,
3455
]
}
]
i want to get the id value if user searched with any ssn or name or by number.the input for search may not be single value that means it may be combination of ssn and name or it may be name,ssn and number .Any combination of name number ,ssn may be inputs .i have to get id value if the inputs matches using php .i used xpath for xml but i want to search fron json.can someone suggest me with any idea..thank you...

To search user ID by analyzing JSON string use the following approach with array_filter and array_intersect_assoc functions:
$json_str = '[ { "id":1.25, "name":"rose", "Number":15, "SSN":[ 12345, 3455 ] }, { "id":1.15, "name":"orchid", "Number":7, "SSN":[ 12345, 3455 ] }]';
$decoded = json_decode($json_str, true);
// base search structure
$search_structure = ['name' => "", 'Number' => 0];
// let's say, the following inputs have come from API (some of them may be empty or omitted)
$number = 7;
$ssn = "3455";
if ($number && is_numeric($number)) $search_structure['Number'] = $number;
$search_structure = array_filter($search_structure); // filtering out empty params
$count_params = count($search_structure);
$user_id = 0;
foreach ($decoded as $item) {
if ($count_params == count(array_intersect_assoc($search_structure, $item))) {
if (!$ssn || ($ssn && in_array($ssn, $item['SSN']))) {
$user_id = $item['id'];
break;
}
}
}
print_r(($user_id)? "User id: $user_id" : "User with specified params not found!");
The output:
User id: 1.15

Lets $json contains an array string
$ar = json_decode($json, true);
$id = false;
foreach ($ar as $i)
if ($i["name"] == "rose" and $i["Number"] == 15)
{ $id = $i["id"]; break; }
if ($id !== false) {
// use $id
}

Preferably, convert the json data to native PHP Object and then using foreach, loop over the object and extracting the ID of the Objects that match the given SSN Number. The result of the extraction would be assigned to an array. Below is a Commented procedure of 1 possible way of going about this:
<?php
// WE ASSUME, JUST FOR TESTING PURPOSES THAT THE SSN NUMBER WE ARE LOOKING FOR IS 4567
$ssnNumber = 4567; //3455;
// CREATE A NEW ARRAY VARIABLE TO HOLD THE IDs YOU DESIRE & INITIALIZE IT TO AN EMPTY ARRAY
$arrIDS = array();
$jsonData = '[
{
"id" :1.25,
"name" :"rose",
"Number" :15,
"SSN" :[
12345,
3455
]
},
{
"id" :1.15,
"name" :"orchid",
"Number" :7,
"SSN" :[
12345,
3455
]
},
{
"id" :1.75,
"name" :"orchid",
"Number" :79,
"SSN" :[
4567,
89012
]
}
]';
// CONVERT $jsonData TO NATIVE PHP OBJECT
$objJson = json_decode($jsonData);
// LOOP THROUGH THE PHP OBJECT & TEST IF A GIVEN SSN EXIST.
foreach($objJson as $key=>$data){
// CHECK IF THE $data->SSN IS SET:
if(isset($data->SSN) && is_array($data->SSN)){
// CHECK IF THE SSN ARRAY CONTAINS THE GIVEN SSN NUMBER.
if(in_array($ssnNumber, $data->SSN)){
$arrIDS[] = $data->id;
}
}
}
var_dump($arrIDS); // DISPLAY: array (size=1) 0 => float 1.75
Alternatively, one could as well encapsulate the above Routine withina Function for re-usability like so:
<?php
function getIDBySSN($jsonData, $ssnNumber){
$arrIDs = array();
$objJson = json_decode($jsonData);
// LOOP THROUGH THE PHP OBJECT & TEST IF A GIVEN SSN EXIST.
foreach($objJson as $key=>$data){
// CHECK IF THE $data->SSN IS SET:
if(isset($data->SSN) && is_array($data->SSN)){
// CHECK IF THE SSN ARRAY CONTAINS THE GIVEN SSN NUMBER.
if(in_array($ssnNumber, $data->SSN)){
$arrIDs[] = $data->id;
}
}
}
return $arrIDs;
}
var_dump(getIDBySSN($jsonData, $ssnNumber)); // PRODUCES THE SAME RESULT
Test it HERE:

Related

PHP How to properly merge arrays for following json structure

So i tried a lot of possible codes out but i can't seem to find a proper solution.
First let's start with the the wished array (i will show it in a json format as it's easier to read)
{
"transaction": {
"input": [
{
"address": "a",
"value": 4294967295
},
{
"address": "b",
"value": 51515
}
],
"output": [
{
"address": "aa",
"value": 551
},
{
"address": "bb",
"value": 66564
}
]
}
}
I'm using 2 foreach loops to get data that i wanna put in inputs & outputs
Here's the code im using:
//Get Output Addresses & Value
$tmp_array = array();
foreach($json['result']['vout'] as $a)
{
$value = $a['value'];
$address = $a['scriptPubKey']['addresses'][0];
$tmp_array = array('wallet' => $address, 'value' => $value);
$input = array_merge($input, $tmp_array);
};
$input = array('inputs' => $tmp_array);
$input = json_encode($input);
print_r($input);
That's the code for me getting the data and trying to put it into the array. Now i have a problem, it only adds data from the last iteration of the loop. I'm trying to get a code that gets it in a strucuture like above. Whatever solution gets sent, it should be applicable so i can paste the same code in the other loop that is for the outputs
You are assigning the $input variable after the loop with the value of $tmp_array which will be the value from the last iteration, as you described. To fix this you should initialize the $input array as empty array at the beginning and merge that with the new data:
//Get Output Addresses & Value
$inputs = array();
foreach($json['result']['vout'] as $a)
{
$value = $a['value'];
$address = $a['scriptPubKey']['addresses'][0];
$tmp_array = array('wallet' => $address, 'value' => $value);
$inputs[] = $tmp_array; // push to array
};
$input = json_encode(array('inputs' => $inputs));
print_r($input);

JSON Get the name of dynamically changing key with PHP

I am having trouble getting the name of a dynamic key from a JSON string.
I am using PHP
This is a sample of the JSON
{
"_text": "this is a test",
"entities": {
"dynamic_key": [
{
"confidence": 0.99,
"value": "thi is the answer"
}
]
},
"msg_id": "1234532123"
}
I am using foreach to go trough the json key and get the values
foreach ($json as $obj) {
$search_term = $obj->_text;
$msg_id = $obj->msg_id;
}
But I am not sure how to get the value of the "dynamic_key" which changes every time, and because of that I also cannot get the values of "confidence and value" keys.
Any ideas on how to approach this?
Followed #Dimi, solution. This is what I ended up with
$data=json_decode($json,true);
foreach ($data['entities'] as $key=>$val)
{
echo "Entity: $key";
foreach ($data['entities'] as $keys){
$conf = $keys[0]['confidence'];
$answer = $keys[0]['value'];
echo "conf: $conf, answ: $answer";
}
}
Can you provide a couple more examples?
Or try this code and let us know if it breaks
<?php
$json='{
"_text": "this is a test",
"entities": {
"dynamic_key": [
{
"confidence": 0.99,
"value": "thi is the answer"
}
]
},
"msg_id": "1234532123"
}';
$data=json_decode($json,true);
foreach ($data['entities'] as $key=>$val)
{
echo "VALUE IS $key\n values are ";
var_dump($val);
}
Using the data you've shown, there doesn't seem to be an array for the starting JSON.
But with that data the following will use foreach to both fetch the key and the data and then another sub-loop to fetch the confidencevalue...
$search_term = $json->_text;
$msg_id = $json->msg_id;
foreach ( $json->entities as $key => $entities ) {
echo $key.PHP_EOL;
foreach ( $entities as $entity) {
echo $entity->confidence.PHP_EOL;
}
}
If you decode the JSON as an array and if the dynamic key is the only key under entities, then:
$array = json_decode($json, true);
$dynamic = current($array['entities']);
$confidence = $dynamic['confidence'];
$value = $dynamic['value'];
Or shorter:
$confidence = current($array['entities'])['confidence'];
You can probably use reset, current and maybe array_pop etc.

Create JSON response from Parsed XML PHP

I am parsing thorugh a eBay API response. I want to deliver this back to a website cleaner and easier to parse with JavaScript. I successfuly Parsed through the XML... but now turning that into JSON to resend back to the client is giving me some headaches.
NOTE: $resp is the response from eBay. It's their full length XML that is successfully parsed with the code below.
For example... $valueName could be Grade. And then I go into the next foreach loop and get the values for this. These values may be 10, 9.5, 9 etc.
Here is my PHP code.
$arrayName = array();
$arrayValue = array();
foreach($resp->aspectHistogramContainer->aspect as $name) {
$nameAspect = $name['name'];
//$arrayName["aspectName"] = $nameAspect;
foreach($name->valueHistogram as $value) {
$valueAspect = $value['valueName'];
//$arrayValue["aspectValue"] = $valueAspect;
}
//array_push($arrayName, $arrayValue);
}
echo json_encode($arrayName);
So, without me trying to create my own JSON, I am getting that I need. I echos results and it was similar to this...
NAME
----- Value
----- Value
----- Value
NAME
----- Value
NAME
etc etc
For a JSON response... Im looking for something like...
[
{
"name": "NAME",
"value": ["value", "value"]
}, {
"name": "name",
"value": ["value", "value"]
}
]
Any help and guidance would be greatly appreciated.
eBay's response is like this (there are A LOT more <aspect> and <valueHistogram>)
<getHistogramsResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<ack>Success</ack>
<version>1.13.0</version>
<timestamp>2018-11-07T15:32:20.380Z</timestamp>
<aspectHistogramContainer>
<domainDisplayName>Baseball Cards</domainDisplayName>
<aspect name="Card Manufacturer">
<valueHistogram valueName="Ace Authentic">
<count>19</count>
</valueHistogram>
<valueHistogram valueName="American Caramel">
<count>2024</count>
</valueHistogram>
<valueHistogram valueName="APBA">
<count>10554</count>
</valueHistogram>
<valueHistogram valueName="Bazooka">
<count>8826</count>
</valueHistogram>
<valueHistogram valueName="Be A Player">
<count>17</count>
</valueHistogram>
<valueHistogram valueName="Bell Brand Dodgers">
<count>334</count>
To encode it (and assuming SimpleXML), then it's just a case of building each internal $aspect data array and then adding the values to it. I use (string) to ensure the data is not stored as a SimpleXMLElement, which can cause side effects...
$arrayName = array();
foreach($resp->aspectHistogramContainer->aspect as $name) {
$aspect = [ "name" => (string)$name['name']];
foreach($name->valueHistogram as $value) {
$aspect["value"][] = (string)$value['valueName'];
}
$arrayName[] = $aspect;
}
echo json_encode($arrayName);
with the sample XML, this gives...
[{"name":"Card Manufacturer","value":["Ace Authentic","American Caramel","APBA","Bazooka","Be A Player","Bell Brand Dodgers"]}]
Create one single array $resultArray and store values in it. By maintaining your current code structure with minimal changes, here is the updated code snippet,
$resultArray = array();
$i = 0; // Maintain Array Index value
foreach($resp->aspectHistogramContainer->aspect as $name) {
$resultArray[$i]["aspectName"] = (string)$name['name'];;
foreach($name->valueHistogram as $value) {
$resultArray[$i]["aspectValue"][] = (string)$value['valueName'];
}
$i++; // Increment array index to store next value
}
echo json_encode($resultArray);
$results = array();
// Parse the XML into a keyed array
foreach($resp->aspectHistogramContainer->aspect as $name) {
$nameAspect = (string) $name['name'];
$values = array();
foreach($name->valueHistogram as $value) {
$values[] = (string) $value['valueName'];
}
$results[$nameAspect] = $values;
}
// This keeps things simple - rewrite to the required JSON format
$outputForJSON = array();
foreach ($results as $name => $values) {
$outputForJSON[] = array(
"name" => $name,
"values" => $values
);
}
echo json_encode($outputForJSON);

Creating new JSON by reading distinct JSON array elements in PHP

I have a JSON object that looks something like this
OBJECT $deals
[
{
"deal_id": 124563
"merchant_id": 123
"merchant_name": Merchant1
}
{
"deal_id": 456789
"merchant_id": 123
"merchant_name": Merchant1
}
{
"deal_id": 46646
"merchant_id": 456
"merchant_name": Merchant2
}
]
What I am trying to do is this right now
$category_merchants = array();
foreach ($deals as $deal) {
array_push($category_merchants, $deal->merchant_id, $deal->merchant_name)
}
$category_merchants = json_encode($category_merchants);
The new JSON object has all the merchants from the original JSON. Is there an easy way to just get the distinct merchants (merchant_name, merchant_id) in the new JSON with counts of how many times they were in the original JSON?
use array_map() like this:
array_map(function($v){return [$v->merchant_id, $v->merchant_name];}, $array);
Convert json to array
$array = json_decode($deals);
loop array to get unique merchant name
foreach($array as $key => $value) {
$category_merchants[$value['merchant_id']] = $value['merchant_name'];
$category_merchant_count[] = $value['merchant_id']; //this is to count number of merchant occurance
}
Convert category_merchants back to json
$merchant = json_encode($category_merchants);
Get number of merchant occurance
print_r(array_count_values($category_merchant_count))
One way. Just use the merchant_id as the key and increment the count:
$deals = json_decode($json, true);
foreach ($deals as $deal) {
if(!isset($category_merchants[$deal['merchant_id']])) {
$category_merchants[$deal['merchant_id']] = $deal;
$category_merchants[$deal['merchant_id']]['count'] = 1;
unset($category_merchants[$deal['merchant_id']]['deal_id']);
} else {
$category_merchants[$deal['merchant_id']]['count']++;
}
}
If you need to re-index the array then:
$category_merchants = array_values($category_merchants);

PHP json string: getting an associative array object

I have a json file with data like this (this is a partial view of the file to show structure):
{
"state": {
"ALABAMA": {
"ZOLD": [ "101", "102" ],
"ZNEW": [ "11", "12" ]
},
"ALASKA": {
"ZOLD": [ "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5009", "5010"],
"ZNEW": [ "21", "22", "23", "24", "25", "26", "27", "28", "29", "20"]
}
}
}
What I want to do is search through it to find a value in the ZOLD field = $OLD, then return the value of the corresponding ZNEW array. I've tried going in with foreach and can get the arrays to echo out, but I'm not sure of what the value will be. Here's the code I have:
function translateZone($OLD)
{
$OLD = "5010"; //for testing purposes a constant but will be variable
$zStr = file_get_contents('getnew.json');
$zJson = json_decode($zStr,true);
foreach($zJson as $key=> $jsons)
{
foreach($jsons as $key=>$values)
{
foreach($values as $key=>$vals)
{
$counter=0;
foreach($vals as $key=>$vls)
{
$counter ++;
echo var_dump($vls);//I can see the values,but now what?
if ($vls == $OLD)
{
$zTemp = Help here -some array value of counter??
}
}
}
return $zTemp;
}
}
I've searched through a bunch of other questions but haven't found something close enough to help with the problem.
Additional information: I may or may not know the "state" string (i.e. "Alaska") but I may want to return this information as well based on the found value.
Thanks for the help.
Instead of trying to loop through ZOLD, you could use array_search (assuming that the $OLD value can only appear once in the data). This function will either return a number for the index of the value you search for or false if it cannot find it:
$index = array_search($OLD,$values['ZOLD']);
if ($index !== FALSE) {
$zTemp = $values['ZNEW'][$index];
}
This would replace your two innermost for loop (as you need the other loops to get down to this level) and iterate through each state. At this point as well, $key would be defined to your state name.
Here is another way to complete your task, this one with array_map function:
$jsonArray = json_decode($your_file_content, true);
$oldVal = "5005";
$result = [];
foreach( $jsonArray["state"] as $k => $v ) {
/**
* Here we're building an array or pairs ZOLD => ZNEW values
*/
$pairs = array_map(function($o, $n) {
return [ $o => $n ];
}, $v["ZOLD"], $v["ZNEW"]);
/**
* Filling up the result
*/
foreach( $pairs as $p )
if( isset($p[$oldVal]) )
$result[] = [
"state" => $k,
"ZNEW" => $p[$oldVal]
];
}
var_dump($result);
$result dump will contains a list or assoc arrays with "state" and "ZNEW" keys, if the corresponding ZNEW values will be found

Categories