How to call an array of arrays on php - javascript

I would like to access to the data inside an array of array that I'm sending with ajax to a .php page.
Creating the array of arrays in the function before sending
var xi = new Array(maxests);
$(".mtable").find(".allownumericwithdecimal").each(function(){
var nth = ((i) % maxests) + 3
var alt = $(this).parent().parent().find("td:first").html()
var est = $('.mtable').find("thead tr:first td:nth-child("+nth+")").html()
var pay = $(this).val()
xi[i] = new Array(alt,est,pay);
i++;
})
Output on php:
Array(
[data] => Array
(
[name] =>
[description] =>
[project] => 1
[ae] => [["Alternativa 1","Estado N. 1","1"],["Alternativa 1","Estado N. 2","23"],["Alternativa 2","Estado N. 1","33"],["Alternativa 2","Estado N. 2","43"]]
))
I would like to access the data inside ae.
echo $_POST['data']['ae'][0][0];
I'm trying this one, but not luck. How can I get the value of each one?

If that's a var_dump($_POST) or print_r($_POST), then this
[ae] => [["Alternativa 1","Estado N. 1","1"],["Alternativa 1","Estado N. 2","23"],["Alternativa 2","Estado N. 1","33"],["Alternativa 2","Estado N. 2","43"]]
is a string
$ae=json_decode($_POST['data']['ae']);
echo $ae[0][0]; // what you thought $_POST['data']['ae'][0][0]; would do
foreach ($ae as $a){
print_r($a);
}
http://uk1.php.net/json_decode

Your array appears to be in an array
$ae = $_POST[0]['data']['ae'];
print_r($ae);
Should give you the breakdown of $ae. So in your example the first element of the first array would be
echo $_POST[0]['data']['ae'][0][0];
output:
Alternativa 1
I hope this helps.

Related

Why does PHP json_encode flatten array?

I have this PHP array ($savedRequestDates) of dates:
Array ( [0] => 2018-03-29 10:56:31 [1] => 2018-03-29 10:58:09 [2] => 2018-04-12 11:28:41 [3] => 2018-04-12 13:07:25 [4] => 2018-05-09 13:08:07 )
At the bottom of the same .php page I have this:
<script type="text/javascript">
var sessions = new Array('<?php echo json_encode($savedRequestDates); ?>');
console.log(sessions[0]);
</script>
The console.log(sessions[0]); returns:
["2018-03-29 10:56:31","2018-03-29 10:58:09","2018-04-12 11:28:41","2018-04-12 13:07:25","2018-05-09 13:08:07"]
Why is the JavaScript array flattening at the 0 index? If I try console.log(sessions); it returns an array with one variable, not 5, as the php array clearly shows.
Am I missing something here?
This happens because you're wrapping the array from PHP which another array (new Array). Just remove the new Array part and it will work fine.
var sessions = <?php echo json_encode($savedRequestDates); ?>;
From what I see the call to json_encodewill create a full JSON object and not just the content of the array. You are enclosing the entire output of the PHP generated array as index 0 inside the new Array.
So removing the new Array will generate what you are looking for.
Try this:
<script type="text/javascript">
var sessions = <?php echo json_encode($savedRequestDates); ?>;
console.log(sessions);
</script>
And you should see the entire array.

How do you split a string of pipe separated values and return an array?

I have an array like the following:
array(1) {
[0]=>
string(160) "|ad|al|at|ax|ba|be|bg|by|ch|cz|de|dk|ee|es|eu|fi|fo|fr|gb|gg|gi|gr|hr|hu|ie|im|is|it|je|li|lt|lu|lv|mc|md|me|mk|mt|nl|no|pl|pt|ro|rs|ru|se|si|sj|sk|sm|tr|ua|va|"
}
I'm trying to find a way to strip the pipes and turn them each into an array.
Here's the code that will output the results.
<?php
if( in_array( 'gb', get_field('rights_management_control_by_continent_europe') ) or 'gb' == get_field('rights_management_control_by_continent') ) {
?>
STUFF HERE
<?php } ?>
And just out of curiosity, is this doable in JavaScript?
Use the PHP explode tag.
<?php
$arr = ["|ad|al|at|ax|ba|be|bg|by|ch|cz|de|dk|ee|es|eu|fi|fo|fr|gb|gg|gi|gr|hr|hu|ie|im|is|it|je|li|lt|lu|lv|mc|md|me|mk|mt|nl|no|pl|pt|ro|rs|ru|se|si|sj|sk|sm|tr|ua|va|"];
$pieces = explode("|", $arr[0]);
Each item separated by the pipe symbol would be a new item in the away, with ad being [1] as you start with a pipe.
[ and ] can start and close an array
In Javascript you can split string to array by using
s = "a|b|c"
arr = s.split('|')
//access your array
arr[0]
arr[1]
.....
So you have this array, I'll just put it in a variable $old_array:
$old_array = array(0=>"|ad|al|at|ax|ba|be|bg|by|ch|cz|de|dk|ee|es|eu|fi|fo|fr|gb|gg|gi|gr|hr|hu|ie|im|is|it|je|li|lt|lu|lv|mc|md|me|mk|mt|nl|no|pl|pt|ro|rs|ru|se|si|sj|sk|sm|tr|ua|va|");
To split the string on index 0 we use the explode function on the first element in the $old_array array:
$exploded_array = explode("|", $old_array[0]);
The variable $exploded_array will now hold an array with all the pairs of letters as separate elements:
["","ad","al","at","ax","ba","be",...]
In JavaScript it would look a little different but still similar:
var old_array = ["|ad|al|at|ax|ba|be|bg|by|ch|cz|de|dk|ee|es|eu|fi|fo|fr|gb|gg|gi|gr|hr|hu|ie|im|is|it|je|li|lt|lu|lv|mc|md|me|mk|mt|nl|no|pl|pt|ro|rs|ru|se|si|sj|sk|sm|tr|ua|va|"];
var split_array = old_array[0].split('|');
The split_array variable will contain all the pairs of letters as separate elements:
["","ad","al","at","ax","ba","be",...]

Preserving order of an associative PHP array while passing it to javascript through ajax

So Here is my php file code
GetUserArray.php
$Users = array('7'=>'samei', '4'=>"chaya", '10'=>'abetterchutia');
echo json_encode($Users);
and this is my ajax request
$.ajax({
url: './GetUserArray.php',
type: 'POST',
dataType: "json",
success: function(users) {
console.log(users);
$.each( users, function( key, value ) {
console.log(key, value);
});
}
});
now what it gives me is in the console is an object sorted by the keys of that array while i want the orignal order which was 7 4 10 in my php file
Object {4: "chaya", 7: "samei", 10: "abetterchutia"}
4 chutiya
7 sali
10 abetterchutia
The problem with using hashmaps is that they don't actually specify order. Though, in PHP, an array is actually an ordered hashmap, so it does. Once you translate that into an object in Javascript, the order is no longer preserved. The only way to guarantee order in Javascript is to use an array.
So in PHP this works as expected and preserves order.
$arr = [4 => "I'm first", 1 => "I'm second", 3 => "I'm third"];
foreach($arr as $value) {
echo $value, "\n";
}
Which gives us
I'm first
I'm second
I'm third
But encode that to Javascript Object Notation (i.e. JSON) and you get an object, because in Javascript arrays don't have keys, they have indexes.
echo json_encode($arr);
Gives us...
{"4":"I'm first","1":"I'm second","3":"I'm third"}
If you tried to do the same in Javascript with this object you might not get the same order
var obj = {"4":"I'm first","1":"I'm second","3":"I'm third"};
var s = "";
for(var x in obj) {
s += + obj[x] + "\n";
}
document.write("<pre>" + s + "</pre>");
This might give you something more like...
I'm second
I'm third
I'm first
So the only way to fix that is to use an array...
json_encode(array_values($arr));
Now this gives us...
["I'm first","I'm second","I'm third"]
And the order is maintained.
However, if you want to preserve the keys as well, you'll have to create an array of objects.
$json = [];
foreach($arr as $key => $value) {
$json[] = [$key => $value];
}
echo json_encode($json);
Now you get...
[{"4":"I'm first"},{"1":"I'm second"},{"3":"I'm third"}]
Which in javascript, works perfectly as expected...
for(var x in obj) {
for(var n in obj[x]) {
obj[x][n]; // now you can both maintain order and have access to the key
}
}

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);

Extract data series from a JSON array for a Highcharts chart with 2 y-axis

I'm using Highcharts to create a line chart with 2 y-axis. Below is how I build my JSON array from a MySQL query:
$series1 = array();
$series1['name'] = 'V';
$series2 = array();
$series2['name'] = 'Speed';
while($row = $selectQueryResult1->fetch())
{
$dateTimer1 = ($row['dateTimer']+$timeAdd)*1000;
$series1['data'][] = array($dateTimer1,$row['v1']);
$series2['data'][] = array($dateTimer1,$row['speed']);
}
$result = array();
array_push($result,$series1);
array_push($result,$series2);
echo json_encode($result, JSON_NUMERIC_CHECK);
Here is how I call the PHP script in jQuery:
$.post('getData.php', {b: begin,e: end}, function(data){
}
My issue now is how to extract the V data and Speed data into two variables because I need to pass them to the chart as two series of data, e.g. I have tried data[0], etc. Nothing seems to work.
///chart.series[0].setData( eval(vData) );
///chart.series[0].setData( eval(speedData) );
You might want to add json as the 4th argument of your $.post to get the JSON parsed as an object, more info here: jQuery.post().
$.post('getData.php', {b: begin,e: end}, function(data){
}, 'json');
Reading your code tells us the structure of your data is as follows:
Array (
[0] => Array
(
[name] => V
[data] => Array
(
[0] => Array
(
[0] => value of $dateTimer1
[1] => value of $row['v1']
Therefore the data series are:
data[0][data] for V.
data[1][data] for Speed.
Therefore:
chart.series[0].setData( data[0][data] );
chart.series[1].setData( data[1][data] );
When in doubt about a structure, simply print it out:
print_r($data); in PHP.
console.log(data); in JavaScript.

Categories