Get array element by value in similar way like getting by $key - php

Is there a possibility in PHP to get an array element by it's value. What I wan't to do is to update an element without knowing the key but nowing it's value:
$translations = array(
"en" => 123,
"de" => 456,
"es" => 789,
"fr" => 901
);
i know that what i wan't to do can be done with an foreach loop:
foreach($translations as $lang=>$id):
if($id == 123) $translations[$lang] = 0;
endforeach;
But is there any possibility to avoid this loop and to automatically set it?

You are looking for array_search():
if(false!==($key = array_search(123, $translations)))
{
$translations[$key] = 0;
}
-be aware that value can be non-unique, so array_search() will find only first key. If you need all of them, you'll have to either iterate through array with foreach or use something like array_walk()

You should use this :
$translations[array_search('123', $translations)] = 0;
Edit: use the solution proposed by Alma Do Mundo, he is right about checking the return value

You can do it in this way also.
Use array_keys function with search_values parameter. It will give you the array of keys which are having these values. Then you can update the original array based on the new array.
It will take care of all the duplicate values also.
$translations = array(
"en" => 123,
"de" => 456,
"es" => 789,
"fr" => 901,
"it" => 123
);
$arr=array_keys($translations,$seach_value);
if(count($arr)){
foreach($arr as $key => $value){
$translations[$value]=$new_value;
}
}

Related

Simplify PHP array with same items

I have this PHP array:
$this->user_list = array( 0 => 'Not paid',1 => 'Not paid', 2 => 'Not paid', 7 => 'Waiting, 15 => 'Waiting', 10 => 'Cancelled' );
How can I simplify this array as the id numbers are different, but some of them have same status?
I tried it like this:
$this->user_list = array( [0,1,2 => 'Not paid'],[7,15 => 'Waiting'],10 => 'Cancelled' );
but it doesn't work as expected.
Basically I want to achieve this:
echo $this->user_list[15] should give me Waiting, echo $this->user_list[10] should give me Cancelled, etc. So this is working in my first array very well, I am just thinking about grouping duplicate names there.
As mentioned by other contributors, there is no native support in the PHP grammar for your intended use case. As clearly stated in the PHP: Arrays documentation:
An array can be created using the array() language construct. It takes any number of comma-separated key => value pairs as arguments.
So basically each element in an array is a key => value pair, which means you cannot associate multiple keys to a single element.
This also explains why your first tentative didn't work:
$this->user_list = array( [0,1,2 => 'Not paid'],[7,15 => 'Waiting'],10 => 'Cancelled' );
If you don't specify a key for an element, PHP uses a progressive index (0, 1, ...). So basically in the example above, the first zero is not actually a key, but a value, and PHP binds it to the key = 0. Maybe it could be easier for you to understand how it works if you print a var_dump or print_r of $this->user_list. You would get something similar to the following structure (NOTE: I have simplified the structure to make it more clear):
[
0 => [
0 => 0
1 => 1
2 => "Not paid"
],
1 => [
0 => 7,
15 => "Waiting"
],
10 => "Cancelled"
]
So how do we resolve this problem? Well... actually there is no need to contort the structure by swapping keys with values as other contributors seem to suggest. Changing the structure might simplify your "data entry" work but might also create big issues in other parts of the program because who knows, maybe accessing the invoice data by "ID" is simply more efficient than by "status" ... or something.
Since PHP does not provide such a feature out of the box, I believe a better solution would be to develop our own function; a good starting point could be the one in the example below.
function explode_array($config, $sep = ',') {
$res = [];
foreach($config as $configKey => $value) {
// split key values
$keys = explode($sep, $configKey);
foreach($keys as $key) {
$res[$key] = $value;
}
}
return $res;
}
$config = [
'0,1,2' => 'Not paid',
'7,15' => 'Waiting',
'10' => 'Cancelled'
];
$myArr = explode_array($config);
print_r($myArr);
The idea is quite simple: since we cannot use an array as key we leverage the next best data type, that is a CSV string. Please note there is no error handling in the above code, so the first thing you may want to do is adding some validation code to the explode_array (or however you wish to name it) function.
you should use like this. if id number is invoice id or something else and other value is there status about it.
$arr = array(
'Not paid' => [0,1,2] ,
'Waiting' => [5,6],
'Cancelled' =>[8]
);
foreach($arr as $key => $val){
foreach($val as $keys => $vals){
echo "invoiceid ".$vals ." status ".$key;
echo"<br>";
}
}
// for only one status you can use like this
foreach($arr['Not paid'] as $key => $val){
echo $val;
echo"<br>";
}
just try to run this and check output.
PHP has no built-in function or structure for handling cases like this. I'd use a simple array value-cloning function to map your duplicates. Simply have one instance of each status, then map the aliases, and then run a function that clones them in. As follows:
// Status list:
$ulist = [ 0 => 'Not paid', 7 => 'Waiting', 10 => 'Cancelled' ];
// Alternative IDs list, mapped to above source IDs:
$aliases = [ 0 => [1,2], 7 => [15] ];
// Function to clone array values:
function clone_values(array &$arr, array $aliases)
{
foreach($aliases as $src => $tgts) {
foreach($tgts as $tgt) {
$arr[$tgt] = $arr[$src];
}
}
ksort($arr); // If the order matters
}
// Let's clone:
clone_values($ulist, $aliases);
This results in the following array:
array(6) {
[0] · string(8) "Not paid"
[1] · string(8) "Not paid"
[2] · string(8) "Not paid"
[7] · string(7) "Waiting"
[10] · string(9) "Cancelled"
[15] · string(7) "Waiting"
}
....which can be accessed as you expect, here $ulist[2] => Not paid, etc. If the use case is as simple as illustrated in the OP, I'd personally just spell it out as is. There's no dramatic complexity to it. However, if you have dozens of aliases, mapping and cloning begins to make sense.
As said in the comments, you can't have multiple keys with one value. The best way is to use the keyword => [ number, number, number...] construction.
//set a result array
$result = [];
//loop the original array
foreach ( $this->user_list as $number => $keyword ){
//if the keyword doesn't exist in the result, create one
if(!isset ( $result [ $keyword ] ) ) $result[ $keyword ] = [];
//add the number to the keyword-array
$result[ $keyword ] [] = $number;
}

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.

What is the reverse of (object) array (key => value) in PHP?

Is there a fast way to return a key when you know its value in PHP?
For example, if you have:
$Numbers = (object) array ( "0" => 0, "1" => 1, "2" => 3, "3" => 7, "4" => 13 );
is there a way to return:
echo re(13); // Print 4
One way I could think of is to build a function specifically for this, but I was wondering if there is a better way.
There is array_search:
$key = array_search(13, (array) $Numbers);
See http://ua2.php.net/array_search
As several other people have mentioned, array_search does what you asked. But if you want an array of ALL the keys that contain the value instead of only the first, you can use array_keys.
print_r(array_keys($Numbers, 13)); // print Array ( [0] => 4 )
http://www.php.net/manual/en/function.array-keys.php
if you are certain that you have unique keys:
$flipped = array_flip($array);
$key = $flipped[$knownValue];
return $key;
Otherwise, use array_search:
return array_search($knownValue, $array);
The first approach may be better if you do a number of lookups, and have unique values. The second approach returns the first matching key in case of multiple values.
http://php.net/array_search
echo array_search($valToSearch, (array) $Numbers);
http://php.net/manual/en/function.array-search.php

Best way to refer index which contains in array

In php I'm willing to check the existence of indexes that match with another values in array.
$indexes = array("index", "id", "view");
$fields = array(
"index" => 5,
"id" => 7,
"form" => 10,
"date" => 10,
);
MY ideal result is, in this case, to get "form" and "date". Any idea?
Try
$fields_keys = array_keys($fields);
$fields_unique = array_diff($fields_keys, $indexes);
The result will be an array of all keys in $fields that are not in $indexes.
You can try this.
<?php
$indexes = array("index", "id", "view");
$fields = array(
"index" => 5,
"id" => 7,
"form" => 10,
"date" => 10,
);
$b = array_diff(array_keys($fields), $indexes);
print_r($b);
You can use array_keys function to retrieve keys of a array
Eg:
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
Outputs
Array
(
[0] => 0
[1] => color
)
PHP Documentation
Your question is a little unclear but I think this is what you're going for
array_keys(array_diff_key($fields, array_fill_keys($indexes, null)));
#=> Array( 0=>"form", 1=>"date" )
See it work here on tehplayground.com
array_keys(A) returns the keys of array A as a numerically-indexed array.
array_fill_keys(A, value) populates a new array using array A as keys and sets each key to value
array_diff_key(A,B) returns an array of keys from array A that do not exist in array B.
Edit turns on my answer got more complicated as I understood the original question more. There are better answers on this page, but I still think this is an interesting solution.
There is probably a slicker way than this but it will get you started:
foreach(array_keys($fields) as $field) {
if(!in_array($field, $indexes)) {
$missing[] = $field;
}
}
Now you will have an array that holds form and date.

Categories