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

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.

Related

How do I pass array keys to an array in PHP [duplicate]

This question already has answers here:
Create an assoc array with equal keys and values from a regular array
(3 answers)
Closed 6 years ago.
I have this array:
$a = array('b', 'c', 'd');
Is there a simple method to convert the array to the following?
$a = array('b' => 'b', 'c' => 'c', 'd' => 'd');
$final_array = array_combine($a, $a);
Reference: http://php.net/array-combine
P.S. Be careful with source array containing duplicated keys like the following:
$a = ['one','two','one'];
Note the duplicated one element.
Be careful, the solution proposed with $a = array_combine($a, $a); will not work for numeric values.
I for example wanted to have a memory array(128,256,512,1024,2048,4096,8192,16384) to be the keys as well as the values however PHP manual states:
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
So I solved it like this:
foreach($array as $key => $val) {
$new_array[$val]=$val;
}

Modify value of a deep key in an associative array [duplicate]

This question already has answers here:
How to access and manipulate multi-dimensional array by key names / path?
(10 answers)
Closed 6 years ago.
Let's assume we have a simple $array like the following.
$array = array(
'a' => array(
'b' => array(
'c' => 'd'
),
'e' => 'f'
),
'g' => 'h'
);
Given an arbitrary array of $keys = array('a', 'b', 'c') and a value $value = 'i', I would like to change value of $array['a']['b']['c'] to i.
For simplicity, let's assume that elements of $keys are all valid, i.e. for any positive j, $keys[j] exists and is a child of $keys[j - 1].
I came up with a solution by passing a reference to the array and looping over keys but my implementation seems a bit ugly. Is there any straight forward way of doing this?
// current key index (starting at 0)
$i = 0;
// current array (starting with the outermost)
$t = &$array;
// continue until keys are exhausted
while ($i < count($keys) - 1) {
// update array pointer based on current key
$t = &$t[$keys[$i++]];
}
// update value at last key
$t[$keys[$i]] = $value;
http://sandbox.onlinephpfunctions.com/code/0598f00ab719c005a0560c18f91ab00154ba9453

php - Why does key of first element of an associative array cannot be zero?

I am new to associative array concept of php. I had never used associative array before this. I came through an example, and got the following code:
function isAssoc($arr)
{
return array_keys($arr) !== range(0, count($arr) - 1);
}
echo(var_dump(isAssoc(array("0" => 'a', "1" => 'b', "2" => 'c'))).'<br />'); // false
echo(var_dump(isAssoc(array("1" => 'a', "1" => 'b', "2" => 'c'))).'<br />'); //true
echo(var_dump(isAssoc(array("1" => 'a', "0" => 'b', "2" => 'c'))).'<br />'); // true
echo(var_dump(isAssoc(array("a" => 'a', "b" => 'b', "c" => 'c'))).'<br />'); // true
The above function is used to tell whether the array is associate array or not.
I have this doubt why:
array("0" => 'a', "1" => 'b', "2" => 'c')
is not an associative array as it returns false. Whereas,
array("1" => 'a', "0" => 'b', "2" => 'c') //OR
array("1" => 'a', "1" => 'b', "2" => 'c')
is an associative array?
The term "associative array" in the PHP manual is used to differentiate from "indexed array". In PHP, all arrays are by definition associative in that they contain key/value pairs (the association). However, the documentation aims to refer to "associative" when it means "non-indexed", for clarity. This is the important point.
So what is an "indexed array"? By "indexed", it is meant that the keys of the array are starting at 0 and incrementing by one. Whether the keys are explicitly set at definition (array(0 => 'a', 1 => 'b')) or implicit (array('a', 'b')) makes no difference. Any other sequence of keys would be referred to as "associative".
Note that how the PHP manual uses the term "associative" doesn't necessarily correlate precisely with the same term's use elsewhere.
All arrays in PHP are associative, you can consider it to be tuple if all keys are numeric (integers but not necessarily of that type), continuous and start from 0.
Simple check would be:
function is_assoc(array $array)
{
$keys = array_keys($array);
$keys_keys = array_keys($keys);
return $keys_keys !== $keys;
}
It would yield same results as the one you've linked to/used.
A hint here would be excerpt from json_decode documentation:
assoc
When TRUE, returned objects will be converted into associative arrays.
Even if it returns "numeric" and "indexed" array it's still associative.
Another example would be:
$array = ["0" => "a", "1" => "b", "2" => "c"]; # numeric, continuous, starts from 0
json_encode($array); # (array) ["a","b","c"]
While:
$array = ["0" => "a", "2" => "b", "3" => "c"]; # numeric, NOT continuous, starts from 0
json_encode($array); # (list) {"0":"a","2":"b","3":"c"}
The function you're referring to has flaws and it is not authoritative about the fact whether or not an array in PHP is associative or not.
In-fact, in PHP it is not strictly defined what the term associative array actually means.
However it is important to understand that
PHP is loosely typed
PHP differs in array keys between integer (bool, NULL, float, integer, numeric string represented as integer) and string (nun-numeric strings) for keys.
Most likely an associative array in PHP is one where inside the array (that is after creating it, not while it seems when writing the array definition) that all keys in that array are strings.
But keep in mind that no set-in-stone definition exists. PHP arrays are just a mixture of array and hash-map where you need to know both without having both properly differentiated and the need to keep in mind the difference between numeric and non-numeric keys and how the loosely type-system of PHP converts for the array key needs.
First page to go as usual:
http://php.net/language.types.array
For those who really can only understand it with code, here the pony goes:
function is_array_assoc(array $array) {
return is_array($array);
}
If you can ensure that you're not using an error-handler that catches catchable errors, then the following code is correct, too:
function is_array_assoc(array $array) {
return TRUE;
}
The later example makes it perhaps a bit more clear that all arrays in PHP are associative.

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

json_encode($array) reverse order of my php array

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

Categories