Offset with an array of unknown length - php-5.6

I building an array from an other.
I have the keys and the values but I don't know how deep can be my new array
I was using the eval function but SONAR refuses it. So I have to find an other way.
$splitpair[0] = array("key1", "key2", "...", "keyN");
$splitpair[1] = "val1";
$returnArray[$splitpair[0]] = $splitpair[1];
I want my returned array like this: $returnArray[key1][key2][...][keyN] = "val1";

you can iterate over your indexes and move a reference to point to the last nested array
`
$returnArray = [];
$buffer = &$returnArray;//buffer points to $returnArray
$array = array('key1','key2','key3');
foreach($array as $index){
if(!(isset($buffer[$index])&&is_array($buffer[$index]))){
$buffer[$index]=[]; //if $buffer[$index] is not an array, initialize it
}
$buffer=&$buffer[$index];//buffer points to the last nested array ($returnArray['key1']['key2']....[$index])
}
$buffer='val1';
var_dump($returnArray);
`

Related

Delete elements by name from JSON?

I am trying to drop elements from JSON. Here is my code:
String test = '[{
"type":"new",
"color":"red",
"items": ["aa","bb", "cc"]
}]';
var myJson = jsonDecode(test);
var result = myJson.where((a)=> a != 'items');
print(result);
It does not work. I need to drop items and get:
[{"type":"new","color":"red"}]
In the JSON, test array contains one object item with a property items. Thus, filtering is not caching it.
To remove items, you need to map over items and remove the items key from each.
UPDATED:
var result = myJson.map((a)=> {a.remove('items'); return a;} );

Loop through JSON Structure in Perl

How to fill list with JSON data?
Here's my code:
my $groups = get_groups($t);
my #group;
my $i = 0;
do {
push(#group, {
groups => [
{ type => $groups->{groups}->[$i]->{type} , group => $groups->{groups}->[$i]->{group} },
]
});
$i++;
} while ($i < length $groups->{groups});
Here is the json sample:
{
"error":false,
"message":"success",
"group":[
{"type":1,"group":"group1"},
{"type":2,"group":"group2"},
{"type":3,"group":"group3"},
{"type":4,"group":"group4"},
{"type":5,"group":"group5"}
]
}
Function get_groups($t); will return above json. I want to get the array group and put it into list groups. But I got:
Can't use string ("0") as a HASH ref while "strict refs" in use
From the documentation of length:
Returns the length in characters of the value of EXPR. If EXPR is
omitted, returns the length of $_ . If EXPR is undefined, returns
undef.
This function cannot be used on an entire array or hash to find out
how many elements these have. For that, use scalar #array and scalar
keys %hash , respectively.
To get the number of elements in an array reference, you need to dereference it and put it into scalar context.
my $foo = [ qw/a b c/ ];
my $number_of_elements = scalar #{ $foo }; # 3
What you actually want to do is loop over every team in the teams array. No need to get the number of elements.
my #teams;
foreach my $team ( #{ $opsteams->{teams} } ) {
push #teams, {
type => $team->{type},
team => $team->{team},
};
}
There are some extra layers of depth in your code. I'm not sure what they are for. It actually looks like you just want the teams in #teams, which really would be
my #teams = #{ $opsteams->{teams} };

Regular expression to extract a JSON array

I'm trying to use a PCRE regular expression to extract some JSON. I'm using a version of MariaDB which does not have JSON functions but does have REGEX functions.
My string is:
{"device_types":["smartphone"],"isps":["a","B"],"network_types":[],"countries":[],"category":["Jebb","Bush"],"carriers":[],"exclude_carriers":[]}
I want to grab the contents of category. I'd like a matching group that contains 2 items, Jebb and Bush (or however many items are in the array).
I've tried this pattern but it only matches the first occurrence: /(?<=category":\[).([^"]*).*?(?=\])/g
Does this match your needs? It should match the category array regardless of its size.
"category":(\[.*?\])
regex101 example
JSON not a regular language. Since it allows arbitrary embedding of balanced delimiters, it must be at least context-free.
For example, consider an array of arrays of arrays:
[ [ [ 1, 2], [2, 3] ] , [ [ 3, 4], [ 4, 5] ] ]
Clearly you couldn't parse that with true regular expressions.
See This Topic:
Regex for parsing single key: values out of JSON in Javascript
Maybe Helpful for you.
Using a set of non-capturing group you can extract a predefined json array
regex answer: (?:\"category\":)(?:\[)(.*)(?:\"\])
That expression extract "category":["Jebb","Bush"], so access the first group
to extract the array, sample java code:
Pattern pattern = Pattern.compile("(?:\"category\":)(?:\\[)(.*)(?:\"\\])");
String body = "{\"device_types\":[\"smartphone\"],\"isps\":[\"a\",\"B\"],\"network_types\":[],\"countries\":[],\"category\":[\"Jebb\",\"Bush\"],\"carriers\":[],\"exclude_carriers\":[]}";
Matcher matcher = pattern.matcher(body);
assertThat(matcher.find(), is(true));
String[] categories = matcher.group(1).replaceAll("\"","").split(",");
assertThat(categories.length, is(2));
assertThat(categories[0], is("Jebb"));
assertThat(categories[1], is("Bush"));
There are many ways. One sloppy way to do it is /([A-Z])\w+/g
Please try it on your console like
var data = '{"device_types":["smartphone"],"isps":["a","B"],"network_types":[],"countries":[],"category":["Jebb","Bush"],"carriers":[],"exclude_carriers":[]}',
res = [];
data.match(/([A-Z])\w+/g); // ["Jebb", "Bush"]
OK the above was pretty sloppy however a solid single regex solution to extract every single element regardless of the number, one by one and to place them in an array (res) is the following...
var rex = /[",]+(\w*)(?=[",\w]*"],"carriers)/g,
str = '{"device_types":["smartphone"],"isps":["a","B"],"network_types":[],"countries":[],"category":["Jebb","Bush","Donald","Trump"],"carriers":[],"exclude_carriers":[]}',
arr = [],
res = [];
while ((arr = rex.exec(str)) !== null) {
res.push(arr[1]); // <- ["Jebb", "Bush", "Donald", "Trump"]
}
Check it out # http://regexr.com/3d4ee
OK lets do it. I have come up with a devilish idea. If JS had look-behinds this could have been done simply by reversing the applied logic in the previous example where i had used a look-forward. Alas, there aren't... So i decided to turn the world the other way around. Check this out.
String.prototype.reverse = function(){
return this.split("").reverse().join("");
};
var rex = /[",]+(\w*)(?=[",\w]*"\[:"yrogetac)/g,
str = '{"device_types":["smartphone"],"isps":["a","B"],"network_types":[],"countries":[],"category":["Jebb","Bush","Donald","Trump"],"carriers":[],"exclude_carriers":[]}',
rev = str.reverse();
arr = [],
res = [];
while ((arr = rex.exec(rev)) !== null) {
res.push(arr[1].reverse()); // <- ["Trump", "Donald", "Bush", "Jebb"]
}
res.reverse(); // <- ["Jebb", "Bush", "Donald", "Trump"]
Just use your console to confirm.
In c++ you can do it like this
bool foundmatch = false;
try {
std::regex re("\"([a-zA-Z]+)\"*.:*.\\[[^\\]\r\n]+\\]");
foundmatch = std::regex_search(subject, re);
} catch (std::regex_error& e) {
// Syntax error in the regular expression
}
If the number of items in the array is limited (and manageable), you could define it with a finite number of optional items. Like this one with a maximum of 5 items:
"category":\["([^"]*)"(?:,"([^"]*)"(?:,"([^"]*)"(?:,"([^"]*)"(?:,"([^"]*)")?)?)?)?
regex101 example here.
Regards.

JSON - look up values in array

With the following json
{
"Count":0,
"Message":{
"AppId":0
},
"Data":"[{\"application_name\": \"Grand Central\",\"feature_name\": \"1 Click Fix\",\"access_type_id\": 2,\"member_name\": \"GC_Remote_Support_Security\"},{\"application_name\": \"Grand Central\",\"feature_name\": \"Account Details\",\"access_type_id\": 2,\"member_name\": \"GC_Remote_Support_Security\"},{\"application_name\": \"Grand Central\",\"feature_name\": \"Account Summary\",\"access_type_id\": 2,\"member_name\": \"GC_Remote_Support_Security\"}]"
}
how do I go through the Data array, in the most succinct coding manner possible, to see if any feature_name matches a given string?
Since your JSON contains nested, quoted JSON, you will need nested deserializations using LINQ to JSON to parse your Data array. Having done so, you can use use SelectTokens to query with a JSONPath query to find nested properties named feature_name, then check their value:
var testString = "Account Summary";
var found = JToken.Parse(JObject.Parse(jsonString)["Data"].ToString()).SelectTokens("..feature_name").Any(t => (string)t == testString);
Debug.Assert(found == true); // No assert.
Update
If you want the all JObject with a "feature_name" property matching a given value, you can do:
var foundItems = JToken.Parse(JObject.Parse(jsonString)["Data"].ToString())
.SelectTokens("..feature_name")
.Where(t => (string)t == testString)
.Select(t => t.Ancestors().OfType<JObject>().First()) // Get the immediate parent JObject of the matching value
.ToList();

merging json objects in php

how can i merge two json objects in php
one of array is like this
$arr_data = array('id'=>$country_id);
$arr = json_encode($arr_data);
and another one is like this:
$arr_places = json_encode($xmlDoc);
now I want to merge them into a single json object. How can I do this.
It depends very much on what you mean by "merge". Just a plain merge or you will need to eliminate the duplicated attributes?...etc.
The simplest way is just like what xdazz mentioned.
So you should merge the array first and then use json_encode.
$json = json_encode(array_merge($arr_data, $xmlDoc));
Merge the results and then encode.
$arr_data = array('id'=>$country_id);
$res = array_merge( $arr_data, $xmlDoc );
$merged = json_encode($res);
Most of the answers here assume that this is a case where one is confronted with two arrays, rather than objects. OP was asking about merging two objects into a single JSON.
While there are many solutions to this, I've got a hack that goes a step further and actually merges the objects into a single JSON string by converting the objects to JSON strings, then back to associative arrays, and then back to JSON.
Could be an efficiency fail, but does the job :-) Here's a code sample:
/**
* Merges two objects into a single JSON structure
* #param object $obj1
* #param object $obj2
* #return string the resuling JSON string
*/
function mergeToJSON($obj1, $obj2) {
$json1 = json_encode($obj1);
$json2 = json_encode($obj2);
if ($json1 === FALSE OR $json2 === FALSE) {
return "";
}
$array1 = json_decode($json1, TRUE);
$array2 = json_decode($json2, TRUE);
$data = array_merge($array1, $array2);
return json_encode($data);
}
The above mentioned solution is not working for me with PHP version 5.5.12
What I want to is in short append to json strings and form one json string out of it, as explained below:
$str1 = {
timestamp: "2015-04-03T08:08:51+00:00",
user: "admin",
src_ip: "127.0.0.1"
}
$str2 = {
timestamp: "2015-04-03T08:08:51+00:00",
user: "Peter_x",
src_ip: "127.0.0.1"
}
$value1 = json_decode ($str1, TRUE);
$value2 = json_decode ($str2, TRUE);
$combined = array_merge ($value1, $value2);
$combined_json = json_encode ($combined);
file_put_contents("c:\outputfile", $combined_json, FILE_APPEND);
The result is:
{
"timestamp": "2015-04-03T08:08:51+00:00",
"user": "admin",
"src_ip": "127.0.0.1",
}
{
"timestamp": "2015-04-03T08:08:51+00:00",
"user": "Peter_x",
"src_ip": "127.0.0.1",
}
Instead I expect one single json string. Firefox fails to parse it. What surprises me is that in the resulting string the keys are within quotes. (e.g: "timestamp").
Can any one tell me what is wrong with the code or how to join the two json strings to one?