json_encode($array) reverse order of my php array - php

I have json_encode($array) it gives me a list in a different order on google chrome

array_reverse: used to Return an array with elements in reverse order, e.g:
$array = array_reverse($array);
echo json_encode($array,JSON_UNESCAPED_UNICODE);

The encoding is done on the backend by the PHP so Google Chrome has nothing to do with this issue.
Check your array order before you encode it.

check the value in $array using var_dump to make sure, thats the order you want.
Edit: look at the 3rd example in the manual

What does your JSON data look like? If:
{1,2,3}
Your browser will not necessarily preserve the order. But if formatted as a JSON array:
[1,2,3]
Then the order will be preserved.

If your array is associative, but indexed by integers (like $arr1 = ['3' => 'x', '2' => 'a', '1' => 'b'];), the browser (when parsing JSON) assumes that the keys of the array indicate the order in which the values are stored (as in a classical, non-associative array - like $arr2 = ['x','a','b'];).
See for yourself - compare the results of parsing the JSON generated from those two associative arrays - one is indexed by non-integer strings (A), the other one is indexed by integers (even if they are string-typed in PHP) (B).
For both examples the values in PHP are stored in order: 'x', 'a', 'b', and only the keys are different.
A) associative array, indexed by strings
<?php
$arr1 = [
'foo' => 'x',
'bar' => 'a',
'baz' => 'b'
];
$json = json_encode($arr1); // $json is now a string: '{"foo":"x","bar":"a","baz":"b"}'
And then, in the browser:
var jsonData = JSON.parse('{"foo":"x","bar":"a","baz":"b"}');
console.log(jsonData);
// prints {foo: "x", bar: "a", baz: "b"} - the keys are in different order then expected!
B) associative array, indexed by integers (even if they are strings in PHP!)
<?php
$arr1 = [
'3' => 'x',
'2' => 'a',
'1' => 'b'
];
$json = json_encode($arr1); // $json is now a string: '"{"3":"x","2":"a","1":"b"}"'
And then, in the browser:
var jsonData = JSON.parse('"{"3":"x","2":"a","1":"b"}"');
console.log(jsonData);
// prints {1: "b", 2: "a", 3: "x"} - the keys are in different order then expected!
As you see - the JSON parser assumes a classical array when the
indices are integers.
So if you need to maintain the order, I'd suggest switching to a classical array and perhaps adding an order / key field to the JSON (for sorting purposes - if you need it):
$arr1 = [
'3' => 'x',
'2' => 'a',
'1' => 'b'
];
$json = json_encode(array_values($arr1)); // note the array_values() here - but this way you loose the index keys
Another way:
$arr1 = [
'3' => [ 'key' => '3', 'value' => 'x'],
'2' => [ 'key' => '2', 'value' => 'a'],
'1' => [ 'key' => '1', 'value' => 'b'],
];
$json = json_encode(array_values($arr1));
// this way you have both values and keys,
// and the parsed JSON will be in the exact order you want it to be

Related

Moving first value and key to the end on an array [duplicate]

This question already has answers here:
How do I move an array element with a known key to the end of an array in PHP?
(4 answers)
Closed 4 years ago.
I have an array that looks something like this:
'array_1' => [
'A' => 'A', 'B' => 'B', 'C' => 'C',
],
I need to shift the first value and key to the end of the array, so it should look like this:
'array_1' => [
'B' => 'B', 'C' => 'C', 'A' => 'A',
],
I've tried to do it like this:
array_push($arr, array_shift($arr));
But the result is this:
'array_1' => [
'B' => 'B', 'C' => 'C', '0' => 'A',
],
The key for value A changed to 0 but i need it ro remain A. Any suggestions?
array_push does not allow you to enter a key.
Therefore you have to use
$arr['key'] = value
First, do a reset(array). This reset the internal pointer to point at the first element
So that when you use key($arr), it will return the first key.
Then use array_shift() to get the first value in the array
Code:
reset($arr)
$arr[key($arr)] = array_shift($arr);
array_push($arr, array_shift($arr));
This removes the first VALUE of $arr, and then adds it to the end of the array as a value, therefore with a numeric key. Since there are no extant numeric keys, it is assigned key 0. Hence your result.
You need to extract the first pair, and push that:
reset($arr);
list($k, $v) = each($arr);
array_shift($arr);
$arr[$k] = $v;
That said... if you're relying on non-numeric key order (or mixed numeric/non-numeric keys), then I fear that your design might be flawed.
A keypair array (a dictionary, or sometimes hash or map) has no key order in most languages and even several representations (most notably, JSON - even if most JSON libraries usually maintain insertion order). Assuming it has might be setting oneself up for a fall.

Count unique values in a column of an array

I have an array like this:
$arr = [
1 => ['A' => '1', 'C' => 'TEMU3076746'],
2 => ['A' => '2', 'C' => 'FCIU5412720'],
3 => ['A' => '3', 'C' => 'TEMU3076746'],
4 => ['A' => '4', 'C' => 'TEMU3076746'],
5 => ['A' => '5', 'C' => 'FCIU5412720']
];
My goal is to count the distinct values in the C column of the 2-dimensional array.
The total rows in the array is found like this: count($arr) (which is 5).
How can I count the number of rows which contain a unique value in the 'C' column?
If I removed the duplicate values in the C column, there would only be: TEMU3076746 and FCIU5412720
My desired output is therefore 2.
Hope this simplest one will be helpful. Here we are using array_column, array_unique and count.
Try this code snippet here
echo count(
array_unique(
array_column($data,"C")));
Result: 2
combine array_map, array_unique, count
$array = [ /* your array */ ];
$count = count(
array_unique(
array_map(function($element) {
return $element['C'];
}, $array))))
or use array_column as suggested by sahil gulati, array_map can do more stuff which probably isn't needed here.
I had a very similar need and I used a slightly different method.
I have several events where teams are participating and I need to know how many teams there are in each event. In other words, I don't need to only know how many distinct item "C" there are, but how many items TEMU3076746 and FCIU5412720 there are.
The code will then be as is
$nbCs = array_count_values ( array_column ( $array, 'C' ) );
$nbCs will issue an array of values = Array([TEMU3076746] => 3 [FCIU5412720] => 2)
See example in sandbox Sandbox code
$data=array();
$data=[
1 => [
'A' => '1'
'C' => 'TEMU3076746'
]
2 => [
'A' => '2'
'C' => 'FCIU5412720'
]
3 => [
'A' => '3'
'C' => 'TEMU3076746'
]
4 => [
'A' => '4'
'C' => 'TEMU3076746'
]
5 => [
'A' => '5'
'C' => 'FCIU5412720'
]
];
$total_value=count(
array_unique(
array_column($data,"C")));
echo $total_value;
Most concisely, use array_column()'s special ability to assign new first level keys using the targeted column's values. This provides the desired effect of uniqueness because arrays cannot contain duplicate keys on the same level.
Code: (Demo)
echo count(array_column($arr, 'C', 'C')); // 2
To be perfectly clear, array_column($arr, 'C', 'C') produces:
array (
'TEMU3076746' => 'TEMU3076746',
'FCIU5412720' => 'FCIU5412720',
)
This would also work with array_column($arr, null, 'C'), but that create a larger temporary array.
p.s. There is a fringe case that may concern researchers who are seeking unique float values. Assigning new associative keys using float values is inappropriate/error-prone because the keys will lose precision (become truncated to integers).
In that fringe case with floats, fallback to the less performant technique: count(array_unique(array_column($arr, 'B))) Demo

Array keys get lost as they are considered numeric

Let's say there exists an array:
$array = array(
'1001' => 'a',
'1002' => 'b',
'1003' => 'c',
);
Now let's say someone wants reverse that array:
$array = array_reverse($array);
The problem is, that array_reverse seems to cast all numeric values to integers and then resets the indexes:
0 => 'c' - should be '1003' => 'c'
1 => 'b' - should be '1002' => 'b'
2 => 'a' - should be '1001' => 'a'
What someone may have also tried was this - but without any luck (as expected):
$array[(string) $index] = 'a';
You can even experience this yourself here on codepad.
How can this be solved? Do I have to write my own mapping function, which can handle this or is there any other way?
you just need to use the following code:
array_reverse($array, true)
As per php documentation, to preserve keys you must set 2nd parameter to true

PHP: Double square brackets after a variable?

echo $a['b']['b2'];
What does the value in the brackets refer to? Thanks.
This is an array.
what you are seeing is
<?php
$a = array(
'b' => array(
'b2' => 'x'
)
);
So in this case, $a['b']['b2'] will have a value of 'x'.
This is just my example though, there could be more arrays in the tree. Refer to the PHP Manual
Those are keys of a multidimensional array.
It may refer to this array:
$a = array(
"a" => array(
"a1" => "foo",
"a2" => "bar"
),
"b" => array(
"b1" => "baz",
"b2" => "bin"
)
)
In this case, $a['b']['b2'] would refer to 'bin'
This refers to a two dimensional array, and the value inside the bracket shows the key of the array
That means the variable $a holds an array. The values inside of the brackets refer the array keys.
$a = array('b' => 'somevalue', 'b2' => 'somevalue2');
In this case echo'ing $a['b'] would output it's value of 'somevalue' and $a['b2'] would output it's value of 'somevalue2'.
In your example, it's refering to a multi-dimensional array (an array inside of an array)
$a = array('b' => array('b2' => 'b2 value'));
where calling b2 would output 'b2 value'
Sorry if my answer is too simplistic, not sure your level of knowledge :)
$a is an array, a list of items. Most programming languages allow you to access items in the array using a number, but PHP also allows you to access them by a string, like 'b' or 'b2'.
Additionally, you have a two-dimensional array there - an array of arrays. So in that example, you are printing out the 'b2' element of the 'b' element in the $a array.

Reorganize an array by 'id' index of nested arrays

I have an array that looks like this:
Array([0]=>Array([id]=>7 [name]=foo) [1]=>Array([id]=>10 [name]=bar) [2]=>Array([id]=>15 [name]=baz))
Each index contains an another array with various elements including an 'id'. I would like to "go up" a level, such that my top-level array is indexed by the ID element of the corresponding nested arrays, but that index still contains an array with all of the elements that were in the sub arrays?
In other words, how can I use PHP to turn the above array into this:
Array([7]=>Array([id]=>7 [name]=foo) [10]=>Array([id]=>10 [name]=bar) [15]=>Array([id]=>15 [name]=baz))
What you need to do here is extract the ids from each sub-array in your input. If you have these as an array of ids, you are just an array_combine call away from re-indexing your original array to use these ids as the keys.
You can produce such an array of ids using array_map, which leads to:
// input data
$array = array(array('id' => '7', 'name' => 'foo'),array('id' => 10, 'name' => 'bar'));
// extract ids from the input array
$ids = array_map(function($arr) { return $arr['id']; }, $array);
// "reindex" original array using ids as array keys, keep original values
$result = array_combine($ids, $array);
print_r($result);
The syntax I 've used for the anonymous function (first argument to array_map) requires PHP >= 5.3, but you can achieve the same (although a bit less conveniently) with create_function in any PHP version you 'd not be ashamed of using.
See it in action.
In modern, supported versions of PHP, this whole task can be achieved with array_column() alone.
Using null as the second parameter will leave the rows unchanged.
Using id as the 3rd parameter will assign those columnar values as the new first level keys. Be aware that if these columnar values are not unique, subsequently encountered duplicates will overwrite previously encountered rows with the same id value -- this is because keys cannot be duplicates on a given level in an array.
DO NOT bother calling array_combine(), it is simply unnecessary/indirect.
Code: (Demo)
$array = [
['id' => 7, 'name' => 'foo'],
['id' => 10, 'name' => 'bar'],
['id' => 15, 'name' => 'baz'],
];
var_export(
array_column($array, null, 'id')
);
Output:
array (
7 =>
array (
'id' => 7,
'name' => 'foo',
),
10 =>
array (
'id' => 10,
'name' => 'bar',
),
15 =>
array (
'id' => 15,
'name' => 'baz',
),
)
Try this:
$newArray = array();
foreach($oldArray as $key => $value) {
$newArray[$value['id']] = $value;
}
Since PHP 5.5.0, you can shorten the code by using array_column() instead of array_map().
$result = array_combine(array_column($array, 'id'), $array);

Categories