PHP take array key and value from beginning and put at end - php

I have a PHP array that has literal_key => value. I need to shift the key and value off the beginning of the array and stick it at the end (keeping the key also).
I've tried:
$f = array_shift($fields);
array_push($fields, $f);
but this loses the key value.
Ex:
$fields = array ("hey" => "there", "how are" => "you");
// run above
this yields:
$fields = array ("how are" => "you", "0" => "there");
(I need to keep "hey" and not have 0) any ideas?

As far as I can tell, you can't add an associative value to an array with array_push(), nor get the key with array_shift(). (same goes for pop/push). A quick hack could be:
$fields = array( "key0" => "value0", "key1" => "value1");
//Get the first key
reset($fields);
$first_key = key($fields);
$first_value = $fields[$first_key];
unset($fields[$first_key]);
$fields[$first_key] = $first_value;
See it work here. Some source code taken from https://stackoverflow.com/a/1028677/1216976

You could just take the 0th key $key using array_keys, then set $value using array_shift, then set $fields[$key] = $value.
Or you could do something fancy like
array_merge( array_slice($fields, 1, NULL, true),
array_slice($fields, 0, 1, true) );
which is untested but has the right idea.

Related

php extract sub array with specific key

if i have the following array:
array(
'var1' => 123,
'var2' => 234,
'var3' => 345
);
I would like to extract specific parts of this to build a new array i.e. var1 and var3.
The result i would be looking for is:
array(
'var1' => 123,
'var3' => 345
);
The example posted is very stripped down, in reality the array has a much larger number of keys and I am looking to extract a larger number of key and also some keys may or may not be present.
Is there a built in php function to do this?
Edit:
The keys to be extracted will be hardcoded as an array in the class i..e $this->keysToExtract
$result = array_intersect_key($yourarray,array_flip(array('var1','var3')));
So, with your edit:
$result = array_intersect_key($yourarray,array_flip($this->keysToExtract));
You don't need a built in function to do this, try this :
$this->keysToExtract = array('var1', 'var3'); // The keys you wish to transfer to the new array
// For each record in your initial array
foreach ($firstArray as $key => $value)
{
// If the key (ex : 'var1') is part of the desired keys
if (in_array($key, $this->keysToExtract)
{
$finalArray[$key] = $value; // Add to the new array
}
}
var_dump($finalArray);
Note that this is most likely the most efficient way to do this.

Setting a multi-dimensional array value

I have an array that looks like...
$arr = array(
array(
"server_name" => "server_a",
"server_number" => "1",
"server_status" => "OPEN"
),
array(
"server_name" => "server_b",
"server_number" => "2",
"server_status" => "CLOSED"
)
);
I am trying to set the index value of "server_status" in the following way
foreach($arr as $a){
$a['server_status'] = "STATUS_".$a['server_status'];
}
This does not seem to be the correct way to set an array value as nothing seems to be happening, what would be the correct way to perform this task?
You need to iterate by reference:
foreach($arr as &$a) {
$a['server_status'] = ...;
}
(The only difference from your code is the & before $a in foreach.)
Just don't forget to unset the reference after iterating:
unset($a);
Else, writing to this variable later in the code would override the last element of the array.
See foreach documentation.
You need to foreach by reference, like this:
foreach($arr as &$a){
$a['server_status'] = "STATUS_".$a['server_status'];
}
Otherwise it does not modify the item of the current iteration - its a copy.

How to Get The Value Which is being set with GET?

I'm using GET to obtain information (unsensitive, of course) and in a URL such as this: http://www.sample.com/foo.php?KEY=VALUE if I wanted to obtain the text "KEY" from that, is it possible?
Try this
foreach($_GET as $key => $value) {
echo $key; // will print 'KEY'
echo $value; // will print 'VALUE'
}
Search Array for Value, Return Key
You could use array_search, which functions similar to using array_keys with the second argument:
$array = array( "Name" => "Jonathan" );
$key = array_search( "Jonathan", $array );
echo $key; // Name
Note that when searching for strings in this manner, your search will be case-sensitive, so make sure you get the case correct. This will return the first key found that corresponds to your search value. If many keys are found, only the first will be returned.
Retrieve Array Keys in Array
If you want all of your keys, you can use array_keys. This returns an array of keys. From this, you could find the one you want, and then use it to grab the corresponding value from $_GET.
$array = array( "Name" => "Jonathan", "Site" => "StackOverflow" );
$aKeys = array_keys( $array );
print_r( $aKeys );
Which results in the following array:
Array
(
[0] => Name
[1] => Site
)
Retrieve Array of Keys for Search
You can provide an optional second value for this function as well, which is the value for which you would like to get the corresponding key. In the array above (and the same goes for $_GET) I can get the key used for "Jonathan" by searching for "Jonathan":
$array = array( "Name" => "Jonathan", "Site" => "StackOverflow" );
$aKeys = array_keys( $array, "Jonathan" );
print_r( $aKeys );
This results in the following array:
Array
(
[0] => Name
)

How to find the indices of duplicate values in an array

I have two arrays, array1 and array2 that I am using to populate a table, so that array1[5] and array2[5] both fill the same row but I want to write a function that removes both array1[i] and array2[i] if array1[i] is a duplicate of array1[j] for some j less than i, where i is an arbitrary positive integer.
To accomplish this I was to work out the indices of duplicate values in array1 and then use this information to delete the entries from both array1 and array2 for these indices, before populating my table.
Any ideas gratefully received.
Thanks.
The array_unique function removes dupes, but preserves keys. Then you can just iterate through the other array and remove the keys that don't exist in the first one.
$array1 = array_unique($array1);
foreach ($array2 as $key => $val) {
if (!array_key_exists($key,$array1)) unset($array2[$key]);
}
$array1_keys = array_keys($array1); // all keys
$unique = array_keys(array_unique($array1)); // keys of unique values
$duplicate = array_diff($array1_keys, $unique_keys); // keys of the duplicate values
foreach($duplicate as $key){
unset($array2[$key]);
}
Sidenote: Be aware that array_diff uses string casting for comparison. If your array contains non scalar values you should have a look at array_udiff.
Edit: Mingos post in my eyes did not fully suit the question, looks like i was wrong :D
If your array keys are meaningful and not just a 0-based index and you want to keep the duplicate entry with the lowest key (as you indicate might be the case from your question) then you need to sort the array first. If you don't, you will get the first entry in the array for each duplicate value and not entry with the lowest key. Compare
$array = array( 5 => 'foo', 1 => 'bar', 2 => 'foo', 3 => 'bar' );
$array = array_unique( $array );
var_dump( $array );
with
$array = array( 5 => 'foo', 1 => 'bar', 2 => 'foo', 3 => 'bar' );
ksort( $array );
$array = array_unique( $array );
var_dump( $array );
In asociative arrays, you can get easily a counter of item to detect repeated and the first ocurrence with something as simple as (in this case using an associative array, where $array_key is the key to count) using array_count_values:
$index = null;
$array_by_columns = array_count_values(array_column($associative_array, $array_key);
foreach($array_by_columns) as $key => $ocurrences){
if($ocurrences > 1){
$index = $key;
}
}
If you have $index there are repeated element and also is the index of in the array.
A more compacted way in a line:
$index = null;
foreach(array_count_values(array_column($associative_array, $array_key)) as $key => $ocurrences)if($ocurrences > 1) $index = $key;
Data example:
[ARRAY] (start)
n0
KEY = 0
VALUE = {"user":"1","points":"10"}
n1
KEY = 1
VALUE = {"user":"4","points":"10"}
n2
KEY = 2
VALUE = {"user":"5","points":"30"}
n3
KEY = 3
VALUE = {"user":"1","points":"40"}
[ARRAY] (end)
More info:
array_count_values
array_column

How to get last key in an array?

How can I get the last key of an array?
A solution would be to use a combination of end and key (quoting) :
end() advances array 's internal pointer to the last element, and returns its value.
key() returns the index element of the current array position.
So, a portion of code such as this one should do the trick :
$array = array(
'first' => 123,
'second' => 456,
'last' => 789,
);
end($array); // move the internal pointer to the end of the array
$key = key($array); // fetches the key of the element pointed to by the internal pointer
var_dump($key);
Will output :
string 'last' (length=4)
i.e. the key of the last element of my array.
After this has been done the array's internal pointer will be at the end of the array. As pointed out in the comments, you may want to run reset() on the array to bring the pointer back to the beginning of the array.
Although end() seems to be the easiest, it's not the fastest. The faster, and much stronger alternative is array_slice():
$lastKey = key(array_slice($array, -1, 1, true));
As the tests say, on an array with 500000 elements, it is almost 7x faster!
Since PHP 7.3 (2018) there is (finally) function for this:
http://php.net/manual/en/function.array-key-last.php
$array = ['apple'=>10,'grape'=>15,'orange'=>20];
echo array_key_last ( $array )
will output
orange
I prefer
end(array_keys($myarr))
Just use : echo $array[count($array) - 1];
Dont know if this is going to be faster or not, but it seems easier to do it this way, and you avoid the error by not passing in a function to end()...
it just needed a variable... not a big deal to write one more line of code, then unset it if you needed to.
$array = array(
'first' => 123,
'second' => 456,
'last' => 789,
);
$keys = array_keys($array);
$last = end($keys);
As of PHP7.3 you can directly access the last key in (the outer level of) an array with array_key_last()
The definitively puts much of the debate on this page to bed. It is hands-down the best performer, suffers no side effects, and is a direct, intuitive, single-call technique to deliver exactly what this question seeks.
A rough benchmark as proof: https://3v4l.org/hO1Yf
array_slice() + key(): 1.4
end() + key(): 13.7
array_key_last(): 0.00015
*test array contains 500000 elements, microtime repeated 100x then averaged then multiplied by 1000 to avoid scientific notation. Credit to #MAChitgarha for the initial benchmark commented under #TadejMagajna's answer.
This means you can retrieve the value of the final key without:
moving the array pointer (which requires two lines of code) or
sorting, reversing, popping, counting, indexing an array of keys, or any other tomfoolery
This function was long overdue and a welcome addition to the array function tool belt that improves performance, avoids unwanted side-effects, and enables clean/direct/intuitive code.
Here is a demo:
$array = ["a" => "one", "b" => "two", "c" => "three"];
if (!function_exists('array_key_last')) {
echo "please upgrade to php7.3";
} else {
echo "First Key: " , key($array) , "\n";
echo "Last Key: " , array_key_last($array) , "\n";
next($array); // move array pointer to second element
echo "Second Key: " , key($array) , "\n";
echo "Still Last Key: " , array_key_last($array);
}
Output:
First Key: a
Last Key: c // <-- unaffected by the pointer position, NICE!
Second Key: b
Last Key: c // <-- unaffected by the pointer position, NICE!
Some notes:
array_key_last() is the sibling function of array_key_first().
Both of these functions are "pointer-ignorant".
Both functions return null if the array is empty.
Discarded sibling functions (array_value_first() & array_value_last()) also would have offered the pointer-ignorant access to bookend elements, but they evidently failed to garner sufficient votes to come to life.
Here are some relevant pages discussing the new features:
https://laravel-news.com/outer-array-functions-php-7-3
https://kinsta.com/blog/php-7-3/#array-key-first-last
https://wiki.php.net/rfc/array_key_first_last
p.s. If anyone is weighing up some of the other techniques, you may refer to this small collection of comparisons: (Demo)
Duration of array_slice() + key(): 0.35353660583496
Duration of end() + key(): 6.7495584487915
Duration of array_key_last(): 0.00025749206542969
Duration of array_keys() + end(): 7.6123380661011
Duration of array_reverse() + key(): 6.7875385284424
Duration of array_slice() + foreach(): 0.28870105743408
As of PHP >= 7.3 array_key_last() is the best way to get the last key of any of an array. Using combination of end(), key() and reset() just to get last key of an array is outrageous.
$array = array("one" => bird, "two" => "fish", 3 => "elephant");
$key = array_key_last($array);
var_dump($key) //output 3
compare that to
end($array)
$key = key($array)
var_dump($key) //output 3
reset($array)
You must reset array for the pointer to be at the beginning if you are using combination of end() and key()
Try using array_pop and array_keys function as follows:
<?php
$array = array(
'one' => 1,
'two' => 2,
'three' => 3
);
echo array_pop(array_keys($array)); // prints three
?>
It is strange, but why this topic is not have this answer:
$lastKey = array_keys($array)[count($array)-1];
I would also like to offer an alternative solution to this problem.
Assuming all your keys are numeric without any gaps,
my preferred method is to count the array then minus 1 from that value (to account for the fact that array keys start at 0.
$array = array(0=>'dog', 1=>'cat');
$lastKey = count($array)-1;
$lastKeyValue = $array[$lastKey];
var_dump($lastKey);
print_r($lastKeyValue);
This would give you:
int(1)
cat
You can use this:
$array = array("one" => "apple", "two" => "orange", "three" => "pear");
end($array);
echo key($array);
Another Solution is to create a function and use it:
function endKey($array){
end($array);
return key($array);
}
$array = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($array);
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
list($last_key) = each(array_reverse($arr));
print $last_key;
// key3
I just took the helper-function from Xander and improved it with the answers before:
function last($array){
$keys = array_keys($array);
return end($keys);
}
$arr = array("one" => "apple", "two" => "orange", "three" => "pear");
echo last($arr);
echo $arr(last($arr));
$array = array(
'something' => array(1,2,3),
'somethingelse' => array(1,2,3,4)
);
$last_value = end($array);
$last_key = key($array); // 'somethingelse'
This works because PHP moves it's array pointer internally for $array
The best possible solution that can be also used used inline:
end($arr) && false ?: key($arr)
This solution is only expression/statement and provides good is not the best possible performance.
Inlined example usage:
$obj->setValue(
end($arr) && false ?: key($arr) // last $arr key
);
UPDATE: In PHP 7.3+: use (of course) the newly added array_key_last() method.
Try this one with array_reverse().
$arr = array(
'first' => 01,
'second' => 10,
'third' => 20,
);
$key = key(array_reverse($arr));
var_dump($key);
Try this to preserve compatibility with older versions of PHP:
$array_keys = array_keys( $array );
$last_item_key = array_pop( $array_keys );

Categories