Get the first key for an element in PHP? - php

I'm trying to add an extra class tag if an element / value is the first one found in an array. The problem is, I don't really know what the key will be...
A minified example of the array
Array (
[0] => Array(
id => 1
name = Miller
)
[1] => Array(
id => 4
name = Miller
)
[2] => Array(
id => 2
name => Smith
[3] => Array(
id => 7
name => Jones
)
[4] => Array(
id => 9
name => Smith
)
)
So, if it's the first instance of "name", then I want to add a class.

I think I sort of understand what you're trying to do. You could loop through the array and check each name. Keep the names you've already created a class for in a separate array.
for each element in this array
if is in array 'done already' then: continue
else:
create the new class
add name to the 'done already' array
Sorry for the pseudo-code, but it explains it fairly well.
Edit: here's the code for it...
$done = array();
foreach ($array as $item) {
if (in_array($item['name'], $done)) continue;
// It's the first, do something
$done[] = $item['name'];
}

I assume you're looping through this array. So, a simple condition can be used:
$first = 0;
foreach ($arr as $value) {
if (!$first++) echo "first class!";
echo $value;
// The rest of process.
}
To get just the first value of an array, you can also use the old fashioned reset() and current() functions:
reset($arr);
$first = current($arr);

Animuson has it good. There a small addition if I might:
> $done = array();
> foreach ($array as $item) {
> if (in_array($item['name'], $done)) continue;
> // It's the first, do something
> $done[] = $item['name']; }
the in_array() will get slow very fast. Try something like:
$done = array();
foreach ($array as $item) {
$key = $item['name'];
if( !isset( $done[$key] )) {
...
}
$done[$key] = true;
}
btw. Too bad this site doesn't support comments for all users.

Related

PHP, how do you change the key of an array element?

Hello guys, and Happy new year!
How can I add keys to this array
$my_array = array( [0] => 703683 [1] => 734972 [2] => 967385 )
So I would like to add a single key to all values example:
$copy_array = array( ['id'] => 703683 ['id'] => 734972 ['id'] => 967385 )
I tried this solution:
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr['id'] = $value ;
}
Output:
( [id] => 703683 )
You can't. An array key is identifying the element it represents. If you set 'id' to be a specific value, then you set it to be another specific value, then you override the former with the latter. Having separate values as ids is self-contradictory anyway, unless they identify different objects. If that's the case, then you can change your code to
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr[] = ['id' => $value] ;
}
or even
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr[$value] = ['id' => $value] ;
}
but the only use of such a change would be if they have other attributes, which are not included in the codes above, since your question does not provide any specific information about them if they exist at all. If everything is only an id, then you might as well leave it with numeric indexes.

PHP multidimensional array not giving output

I've tried to display this information tons of times, i've looked all over stackoverflow and just can't find an answer, this isn't a duplicate question, none of the solutions on here work. I've a json array which is stored as a string in a database, when it's taken from the database it's put into an array using json_decode and looks like this
Array
(
[0] => Array
(
[0] => Array
(
)
[1] => Array
(
[CanViewAdminCP] => Array
(
[Type] => System
[Description] => Grants user access to view specific page
[Colour] => blue
)
)
)
)
However, when i try to loop through this, it just returns nothing, I've tried looping using keys, i've tried foreach loops, nothing is returning the values, I'm looking to get the Array key so "CanViewAdminCP" and then the values inside that key such as "Type" and "Description".
Please can anybody help? thankyou.
Use a recursive function to search for the target key CanViewAdminCP recursively, as follows:
function find_value_by_key($haystack, $target_key)
{
$return = false;
foreach ($haystack as $key => $value)
{
if ($key === $target_key) {
return $value;
}
if (is_array($value)) {
$return = find_value_by_key($value, $target_key);
}
}
return $return;
}
Example:
print_r(find_value_by_key($data, 'CanViewAdminCP'));
Array
(
[Type] => System
[Description] => Grants user access to view specific page
[Colour] => blue
)
Visit this link to test it.
You have a 4 level multidimensional array (an array containing an array containing an array containing an array), so you will need four nested loops if you want to iterate over all keys/values.
This will output "System" directly:
<?php echo $myArray[0][1]['CanViewAdminCP']['Type']; ?>
[0] fetches the first entry of the top level array
[1] fetches the second entry of that array
['CanViewAdminCP'] fetches that keyed value of the third level array
['Type'] then fetches that keyed value of the fourth level array
Try this nested loop to understand how nested arrays work:
foreach($myArray as $k1=>$v1){
echo "Key level 1: ".$k1."\n";
foreach($v1 as $k2=>$v2){
echo "Key level 2: ".$k2."\n";
foreach($v2 as $k3=>$v3){
echo "Key level 3: ".$k3."\n";
}
}
}
Please consider following code which will not continue after finding the first occurrence of the key, unlike in Tommassos answer.
<?php
$yourArray =
array(
array(
array(),
array(
'CanViewAdminCP' => array(
'Type' => 'System',
'Description' => 'Grants user access to view specific page',
'Colour' => 'blue'
)
),
array(),
array(),
array()
)
);
$total_cycles = 0;
$count = 0;
$found = 0;
function searchKeyInMultiArray($array, $key) {
global $count, $found, $total_cycles;
$total_cycles++;
$count++;
if( isset($array[$key]) ) {
$found = $count;
return $array[$key];
} else {
foreach($array as $elem) {
if(is_array($elem))
$return = searchKeyInMultiArray($elem, $key);
if(!is_null($return)) break;
}
}
$count--;
return $return;
}
$myDesiredArray = searchKeyInMultiArray($yourArray, 'CanViewAdminCP');
print_r($myDesiredArray);
echo "<br>found in depth ".$found." and traversed ".$total_cycles." arrays";
?>

Add values in second array depending upon the values in first array

Here's the situation:
Suppose I have first Array as:
Array(
[0] => Person1
[1] => Person1
[2] => Person2
)
And second array as:
Array(
[0] => 100.00
[1] => 150.25
[2] => 157.15
)
How do I add values (100.00 + 150.25) of second Array and merge them (250.25) so that they belong to Person1 in the first array.
Desired Output:
Array(
[0] => 250.25 // for Person1 in the first Array after adding
[1] => 157.15 // for Person2 in the first Array
)
Any help is highly appreciated. Thank You.
P.S.: All the values are coming from the database.
EDIT 1:
Here's what I have tried, but this outputs the second array as it is:
$sums = array();
$sums = array_fill_keys(array_keys($affiCode + $affiCommAmount), 0);
array_walk($sums, function (&$value, $key, $arrs) {
$value = #($arrs[0][$key] + $arrs[1][$key]);
}, array($affiCode, $affiCommAmount)
);
The arrays are the same size, so you can use a for loop to process them simultaneously:
for($i = 0; $i<count($personArray); $i++)
Within the loop, construct a new array keyed to the values from the first array. If the key does not yet exist, initialize it:
if (!isset($newArray[$personArray[$i]])) {
$newArray[$personArray[$i]] = 0.0;
}
then add the new value to the selected array key:
$newArray[$personArray[$i]] += $valueArray[$i]
When the loop ends, $newArray will look like:
Array(
['Person1'] => 250.25
['Person2'] => 157.15
)
If you want to replace the 'Person1' and 'Person2' keys with numerical indexes, use array_values():
$numericallyIndexedArray = array_values($newArray);
The final code looks like:
$newArray = [];
for($i = 0; $i<count($personArray); $i++) {
if (!isset($newArray[$personArray[$i]])) {
$newArray[$personArray[$i]] = 0;
}
$newArray[$personArray[$i]] += $valueArray[$i];
}
// Optionally return the new array with numerical indexes:
$numericallyIndexedArray = array_values($newArray);
Get the person from first array by index and add the money:
for($i=0;$i<count(arrayPerson);$i++){
$arrayPerson[$i]->addMoney($arrayMoney[$i])
//Or $arrayPerson[$i]->Money += $arrayMoney[$i]
} //$i defines your index in the array.
sql
Better though to make a join in the SQL and sum the money and group by PersonID.
for example:
SELECT person.* COUNT(Money) FROM Person
LEFT JOIN Money
ON person.ID = Money.PersonID
GROUP BY person.ID
Simple foreach loop:
$people = array('Person1', 'Person1', 'Person2');
$values = array(100.00, 150.25, 157.15);
$output = array();
foreach ($people as $key => $person) {
if (! isset($output[$person])) {
$output[$person] = 0;
}
if (! empty($values[$key])) {
$output[$person] += $values[$key];
}
}
// $output = array(2) { ["Person1"]=> float(250.25) ["Person2"]=> float(157.15) }
If you want to do away with the keys in $output, you can use array_values($output)
Here's an example

How to use foreach to get all the GET elements with specific names

He stackoverflow,
Today I am busy with an function witch get's all the elements with specific name. Now I have one problem creating this function. The specific name's are dynamic, so there can be: "conf_1=data&conf_2=data" but also: "conf_1=data&conf_2=data&conf_3=data"
Some code to enlighten you,
foreach($_GET as $key => $value) {
$a++;
if (strpos($key, "conf_$a") === 0) {
$conf[$key] = $value;
}
}
So lets say we have this URL,
naam=name&dom=domain&id=41&conf_1=data&conf_2=data&conf_3=data&this_1=data&this_2=opt1
Now I am trying to get all the conf elements with the foreach loop but I need the $a parameter to be the 1,2 en 3 numbers. And when I try to take all the this elements $a shut give 1 en 2.
How can I declare that or how can I do this with an different loop. The next step is of-course to put the elements into an array like this:
$conf = Array
(
[1] => data
[2] => data
[3] => data
)
$this = Array
(
[1] => data
[2] => data
)
It is important that the numbering is not done automatically. The number in the array shut be the number in the name of the element. Basically conf_1=data has to become [1] => data
I understand that there are multiple ways to do this but I don' t know witch are the best and the fastest ways. The way I am doing it now is complete wrong:
for($a = 0; $a < 99; $a++){
// Get all the data
$conf = array();
foreach($_GET as $key => $value) {
if (strpos($key, "conf_$a") === 0) {
$conf[$key] = $value;
}
}
$finalconf = array();
//order all data
$finalconf[$a] = $conf['conf_' . $a];
print_r ($conf);
print_r ($finalconf);
}
You can try
$list = array();
foreach($_GET as $key => $data)
{
(strpos($key,"conf_") === 0) AND $list[ltrim(strstr($key,"_"),"_")] = $data ;
}
var_dump($list);
Output
array
1 => string 'data' (length=4)
2 => string 'data' (length=4)
3 => string 'data' (length=4)
If you are submitting with a form (rather than with javascript for example), you can make it easier by converting the "conf" input element into an array.
<input name="conf[]" ... >
<input name="conf[]" ... >
<input name="conf[]" ... >
Upon submission, these would be available as an array in the form;
$_GET['conf'] = array('foo', 'bar', 'baz')
This is only helpful if you are submitting an html form.
Try this code:
$conf = array();
function check( $key ) {
if( preg_match( '/conf_([0-9]+)/i', $key, $matches ) ) {
return $matches[ 1 ];
} else {
return false;
}
}
foreach( $_GET as $key => $val ) {
$index = check( $key ) ;
if( $index !== false ) {
$conf[ $index ] = $val;
}
}

next element in a associative php array

This seems so easy but i cant figure it out
$users_emails = array(
'Spence' => 'spence#someplace.com',
'Matt' => 'matt#someplace.com',
'Marc' => 'marc#someplace.com',
'Adam' => 'adam#someplace.com',
'Paul' => 'paul#someplace.com');
I need to get the next element in the array but i cant figure it out... so for example
If i have
$users_emails['Spence']
I need to return matt#someplace.com and if Its
$users_emails['Paul']
i need start from the top and return spence#someplace.com
i tried this
$next_user = (next($users_emails["Spence"]));
and this also
($users_emails["Spence"] + 1 ) % count( $users_emails )
but they dont return what i am expecting
reset($array);
while (list($key, $value) = each($array)) { ...
Reset() rewind the array pointer to the first element, each() returns the current element key and value as an array then move to the next element.
list($key, $value) = each($array);
// is the same thing as
$key = key($array); // get the current key
$value = current($array); // get the current value
next($array); // move the internal pointer to the next element
To navigate you can use next($array), prev($array), reset($array), end($array), while the data is read using current($array) and/or key($array).
Or you can use foreach if you loop over all of them
foreach ($array as $key => $value) { ...
You could do something like this:
$users_emails = array(
'Spence' => 'spence#someplace.com',
'Matt' => 'matt#someplace.com',
'Marc' => 'marc#someplace.com',
'Adam' => 'adam#someplace.com',
'Paul' => 'paul#someplace.com');
$current = 'Spence';
$keys = array_keys($users_emails);
$ordinal = (array_search($current,$keys)+1)%count($keys);
$next = $keys[$ordinal];
print_r($users_emails[$next]);
However I think you might have an error in your logic and what you are doing can be done better, such as using a foreach loop.
You would be better storing these in an indexed array to achieve the functionality you're looking for

Categories