regex pattern for json array and dynamic multi-level array check - javascript

On the page there will be about several hundred elements to which individual keywords are assigned, as in a kind of index.
These keywords are used to dynamically show or hide these elements with JavaScript, depending on whether the searched keywords are found. The keywords are inserted by PHP into the data-tags of the individual elements.
For example, the keyword directory could look like this:
$keywords =
[
'MainCategory1' =>
[
'Category1' =>
[
'Value1' => 0,
'SubCategory1' => [
'Value2' => 0,
'Value3' => 0
]
],
'Category2' =>
[
'Value4' => 0,
'Value5' => 0
]
],
'MainCategory2' =>
[
'Category2' =>
[
'Value2' => 0,
'Value4' => 0
],
'Category3' =>
[
'Value5' => 0,
'Value6' => 0
]
]
];
Some categories and values may occur more than once, depending on which subtopic they are in.
For example, an element has been assigned these keywords:
MainCategory1 > Category1
MainCategory1 > Category2 > Value5
MainCategory2 > Category2 > Value2
The keywords are stored in the backend as a json string and written to the data attributes. For this element:
{"MainCategory1":{"Category1":0,"Category2":{"Value5":0}},"MainCategory2":{"Category2":{"Value2":0}}}
My idea now is to loop through all elements as soon as a keyword is selected and see if the stored JSON string matches "MainCategory1 > Category2 > Value5".
This would correspond in PHP to
isset($keywords['MainCategory1']['Category2']['Value5'])
My questions about this:
How could I make the isset query dynamic in php if I don't know beforehand how many levels the keyword has? This is important for when a keyword is set, to check in the backend whether the keyword is valid at all. I could loop through each level though; is there an alternative for this?
What I'm doing so far:
$arrayString = explode(' > ', $array);
$foundCount = 0;
$currentArray = $keywords;
for($i = 1; $i <= count($arrayString); $i++) {
$key = $arrayString[$i - 1];
$keyExists = array_key_exists($key, $currentArray);
if(!$keyExists)
break;
$currentArray = $currentArray[$key];
$foundCount++;
}
$isKeywordValid = $foundCount == count($arrayString);
I am familiar with regex, but I am having trouble finding a pattern that solves this problem. What does the pattern have to look like if I want to know if "MainCategory1 > Category2 > Value5" matches the JSON string in this particular example? (This convention is only a paraphrase for the different levels. The string can also be parsed differently)

Taken from How to access and manipulate multi-dimensional array by key names / path?, you can walk down the structure using a reference:
function array_isset($path, $array) {
$path = explode(' > ', $path);
$temp =& $array;
foreach($path as $key) {
if(!isset($temp[$key])) { return false; }
$temp =& $temp[$key];
}
return true;
}
Or turn MainCategory1 > Category2 > Value5 into ["MainCategory1"]["Category2"]["Value5"] and evaluate it as an isset:
function array_isset($path, $array) {
$path = '["' . str_replace(' > ', '"]["', $path) . '"]';
eval("return isset(\$array{$path});");
}
Then just do:
if(array_isset('MainCategory1 > Category2 > Value5', $keywords)) {
// code
}

Related

Fetch file and convert JavaScript array into PHP array

I've been searching for a few days now, trying to figure out the best way to solve a problem: I want to fetch a JavaScript file from e.g. GitHub and convert a JavaScript array into PHP.
My first idea was to fetch the page (raw.githubusercontent.com) with PHP (file_get_contents) on server side and then parse it. But it's a multidimensional array, so I think this is complicated and not very flexible.
Example
In JavaScript only the keys are relevant (e.g. https://raw.githubusercontent.com/xxx/example.js)
var cars = {
'Saab': {
'Blue': true,
'Green': true,
...
},
'Volvo': {
'Brown': true
},
'BMW': {
'Black': true
},
...
}
In PHP the content should be combined as a string array:
Array
(
[0] => 'SaabBlue'
[1] => 'SaabGreen'
[2] => 'VolvoBrown'
[3] => 'BMWBlack'
...
)
I would be happy if someone had an idea a short hint ;)
Update:
I think I will do this server side with PHP.
$arr = array();
// fetch the file
$content = file_get_contents('https://raw.githubusercontent.com/xxx/example.js');
// remove all comments and unnecessary lines with RegEx
$content = preg_replace(<RegEx Expression>, '', $content);
foreach(preg_split("/((\r?\n)|(\r\n?))/", $content) as $line){
// filter with strpos and/or preg_match
// [x][ ][ ]
if ( filter ) {
$m = explode("'", $line);
// [ ][x][ ]
} else if ( anyfilter) {
$n = explode("'", $line);
// [ ][ ][x]
} else if ( filter ){
$o = explode("'", $line);
$str = $m[1] . $n[1] . $o[1];
array_push($arr, $str);
}
}
Set all the variables into cookies.
document.cookie = "cars_Saab_Blue="+cars.Saab.Blue;
Do something similar (dpending on the situation) and set everything into 1 or more cookies.
Now by using $_COOKIE['cars_Saab_Blue'] you can get the cookie and use it wherever you want,

Is there a formula to find shortest length required to achieve uniqueness across a set

I'd like to be able to calculate the length of the shortest sub-string required to achieve complete uniqueness.
Lets say I have a varying length list of 32 character UUIDs, but what I'd like to achieve is shortenening them during reference to only be as long as is required to achieve uniqueness in their set. For instance, if I have the following set of UUID's (pipes inserted to illustrate the answer)...
428|07082e1f445e79501bebfa87396af
723|0785bffaf4747865c202dd0924c7f
b65|634be909d4e5590aa0cdc97251eef
3c4|d94c683624d75a273e3186ec65b78
09e|bd42af0404bcf90413e11c5b40fbb
011|004743d65466dae8a9a6bc814ef4b
1f1|889e04e3a453fbf57521de0a70b60
1ac|44707af8d4681875171ad47c61037
42f|7a6236deb4a9ead32ab2e816d73a3
83a|fe22086064eec87704127622b8165
I would only require the first three characters to achieve the same level of uniqueness as if I had used the full 32 character strings.
I'm curious if there is a formula for reaching that value. I know that I could put this in a couple nested loops, but I'd like to know if there is a more elegant or programmatic way of achieving this.
Edit: Just to be clear, the pipes are only to illustrate that I can achieve uniqueness after only 3 characters. The result of the formula/method should be an array of equal length with only the shortest strings derived from the given set, in this case, the first three chars only. Imagine that I want to use these in a URL, and that I can't have any ambiguity, but still want to be able to reference the same records as if I used the full string in each case.
EDIT2: Actually... as I think about it, no need for a result array, only an integer, the min length required in characters.
I managed to create some codes to achieve that. Take a look:
Code 1:
function check_un($array){
$arr = $array;
$len = 1;
$tmp = array();
while (list($key, $value) = each($arr)) {
$v = substr($value, 0, $len);
if (isset($tmp[$v])) {
$tmp = array();
$len++;
reset($arr); // start again
}
$tmp[$v] = true;
}
$tmp = array_keys($tmp);
array_shift($tmp);
return $tmp;
}
Basically, the previous code checks if given substring put as key is already set - meaning it's duplicated. That way, it goes to the beginning of the array and starts checking again with more letters.
Code 2: (smaller, but slower)
function check_un($array){
$array = array_values($array);
$len = 1;
$tmp = array();
for($i = 0; $i < strlen($array[0]); $i++){
if( count(array_unique( $tmp = array_map(function($v) use($len){ return substr($v, 0, $len); }, $array ) )) != count($array) ){
$len++;
}else{
break;
}
}
return $tmp; // this was set in the array_map part
}
Basically, the previous code checks if the quantity of unique elements of a given substring length is the same as the quantity of the original array. That way, if there are any duplicates, the quantity will be smaller, meaning that we need to use more positions.
There used to be a code 3 (the first I tried), but it's only available in the edit history.
You can test them with this:
$values = array(
'42807082e1f445e79501bebfa87396af',
'7230785bffaf4747865c202dd0924c7f',
'b65634be909d4e5590aa0cdc97251eef',
'3c4d94c683624d75a273e3186ec65b78',
'09ebd42af0404bcf90413e11c5b40fbb',
'011004743d65466dae8a9a6bc814ef4b',
'1f1889e04e3a453fbf57521de0a70b60',
'1ac44707af8d4681875171ad47c61037',
'42f7a6236deb4a9ead32ab2e816d73a3',
'83afe22086064eec87704127622b8165'
//,'42807082e1f445e795aaaaaaaaaaaaa' // add this to test with more letters
);
$val = check_un($values);
The result (for both cases):
Array
(
[0] => 428
[1] => 723
[2] => b65
[3] => 3c4
[4] => 09e
[5] => 011
[6] => 1f1
[7] => 1ac
[8] => 42f
[9] => 83a
)
See them in action here:
Code 1;
Code 2.
You can change the returned value to get only the $len variable.
You could utilize Array.prototype.reduce(), Object.hasOwnProperty() recursion; create an object to store values of unique character set, set object name to first two characters if name is not a property of object, else set first n characters until each property in object is unique
var arr = ["42807082e1f445e79501bebfa87396af "
, "7230785bffaf4747865c202dd0924c7f"
, "b65634be909d4e5590aa0cdc97251eef"
, "3c4d94c683624d75a273e3186ec65b78"
, "09ebd42af0404bcf90413e11c5b40fbb"
, "011004743d65466dae8a9a6bc814ef4b"
, "1f1889e04e3a453fbf57521de0a70b60"
, "1ac44707af8d4681875171ad47c61037"
, "42f7a6236deb4a9ead32ab2e816d73a3"
, "83afe22086064eec87704127622b8165"];
var obj = {};
arr.reduce((o, uuid) => {
var n = 1;
(function re(key) {
var curr = uuid.slice(0, key);
if (!o.hasOwnProperty(curr)) {
o[curr] = uuid;
} else {
re(key + 1)
}
}(n))
return obj
}, obj);
console.log(obj, "arr length:", arr.length
, "obj keys length:", Object.keys(obj).length);

Passing nested PHP loop to javascript

I have a PHP array that looks like this:
([NAME] => Array ( [0] => 16 [1] => 12 [2] => 4 [3] => 0 ))
([NAME2] => Array ( [0] => 19 [1] => 19 [2] => 0 [3] => 0 ))
([NAME3] => Array ( [0] => 31 [1] => 29 [2] => 2 [3] => 0 ))
This array is generated by PHP by pulling data from a database.
(The array is much larger than this, but for simplicity, I only included 3 records)
I really need this data to be usable in a script that generates a bar graph. For now, I only need the name and the first record. So, for example, in PHP
<?=$array['NAME'][0]?>
<?=$array['NAME2'][0]?>
would echo the information I need from each, but I'm not sure how to put that into the format I need into javascript.
This is the javascript format that I need:
{ tech: 'NAME', value: $array['NAME'][0] },
{ tech: 'NAME2', value: $array['NAME2'][0] },
{ tech: 'NAME3', value: $array['NAME3'][0] },
{ tech: 'NAME4', value: $array['NAME4'][0] },
...etc
Some type of loop would be preferred because the names can vary.
If it was just PHP I could do it, but I'm not too fluent in Javascript.
Could someone help me come up with a solution?
The good news is that you don't have to know much javascript. Create your data structure as you want it in php, and then use json_encode: http://php.net/manual/en/function.json-encode.php
<?php
$for_chart = array();
foreach($names as $key => $name){
$obj = new stdClass;
$obj->tech = $key;
$obj->value = $name[0];
$for_chart[] = $obj;
}
?>
the result is:
[{"tech":"NAME","value":1},{"tech":"NAME2","value":5},{"tech":"NAME4","value":9}]
You can use it in your javascript like this:
<script>
var my_names = <?=json_encode($for_chart)?>;
alert(my_names[0].value); // alerts "1"
</script>
http://sandbox.onlinephpfunctions.com/code/2682f09fd5515b220402db9c600b70a0501a87d9
If you json_encode the array you have, it comes out to:
{"NAME1":[16,12,4,0],"NAME2":[19,19,0,0],"NAME3":[31,29,2,0]}
which will give you a javascript object to iterate:
If you have the json object in a variable called arrayData:
var gridData = [];
for (var name in arrayData) {
var rowObj = { tech: name, value: arrayData[name][0] };
gridData.append(rowObj);
}
At the end of that, you will have an array of objects that should be what you're looking for in gridData.
If you would echo it in the following format you can JSON to get the data:
[{tech: 'NAME', value: $array['NAME'][0]},{tech: 'NAME', value: $array['NAME'][0]}]
In your js you could do something like the following:
var names = $.getJSON('http://localhost/index.php?name', function(data) {});
This way you have an array in js.
To get the javascript code just iterate over the php array an echo the json records like you want:
<?= foreach($array as $key => $value){
echo "{ tech: '" .$key ."', value: '" .$value[0] ."'},";
}
?>
//Assuming this is your array
$getArray["NAME"] = array(16,12,4,0);
$getArray["NAME2"] = array(19,19,0,0);
$getArray["NAME3"] = array(31,29,2,0);
$newArray = array();
foreach($getArray as $indKey=>$indArrVal) {
$newArray[] = array("tech"=>$indKey, "value"=>$indArrVal[0]);
}
echo json_encode($newArray);
here it is, create a new array, with the required indexes and then stringify it using json_encode

how to convert array from php into js

I have this array value: print_r ($array); which contains 2 data (this is latt and long of my gmap project).
The array is from:
<?php
if(isset($_GET['q'])) {
$q = $_GET['q'];
}
$q = isset($_GET['q']) ? $_GET['q'] : '';
$array = array();
$nsUser="SELECT * FROM cliententry WHERE kampusterdekat=:q";
$uQuery = $mydb->prepare ($nsUser);
$uQuery->execute(array(':q' => $q));
while ($result = $uQuery->fetch(PDO::FETCH_ASSOC)) {
$id=$result['id'];
$googlemap=$result['googlemap'];
//echo $googlemap;
$array[] = $googlemap;
print_r ($array);
}
?>
When I echo, the result will be like this:
Array
(
[0] => -5.364000343425874, 105.24465411901474
)
Array
(
[0] => -5.364000343425874, 105.24465411901474
[1] => -5.362878747789552, 105.24150252342224
)
Point:
What I need is to make the result into this format:
var wwwsitus = [
['<h4>area</h4>', wwwsitus[0]],
['<h4>area</h4>', wwwsitus[1]],
];
where locations (<h4>area</h4>) are removed. So, it must be, as follows:
var wwwsitus = [
[...,...],
[...,....],
];
Note:
Since I've no capable about array in JS, please help me to fix my title based on my issue. Thks in adv.

Is this a JSON array?

Is this a JSON array: http://flamencopeko.net/icons_ajax.php?
Source: http://flamencopeko.net/icons_ajax.txt
$urls = array(); foreach (glob(dirname(__FILE__) . '/ico/*.gif') as $file) { $urls[] = 'http://flamencopeko.net/ico/' . basename($file); };
$index = 0;
if (isset($_GET['index'])) {
$index = (int) $_GET['index'];
if ($index > (count($urls) - 1)) {
// Out of bounds, reset
$index = 0;
}
}
$previous = $index - 1;
$next = $index + 1;
if ($previous < 0) {
$previous = count($urls) - 1;
}
if ($next == count($urls)) {
$next = 0;
}
echo json_encode(array(
'total' => count($urls),
'url' => $urls[$index],
'next' => $next,
'prev' => $previous,
'alls' => $urls
));
I'm trying to use it with php. Works with JavaScript. I've tried json_decode() and more, but no output yet.
What you've shown is a JSON object. It contains an array inside, but the entire thing is an object. Think of it this way-JSON could be a key-value data, making it an object, or it could be an array-single values, no keys such as
[1,2,3,"some string",34,"another string"]
What you've shown is a completely valid JSON object. Whether it will suit your needs-we cannot say. You could take a look at json.org for the exact specifications and what is considered a valid JSON.
Also any array passed on to json_encode() will output a valid JSON.
I like to use the online json viewer at http://jsonviewer.stack.hu/ - which shows you have a valid json object; which you could use to see that it consists of some header info and an array of 406 images in the 'alls' array.

Categories