Below is dump of how my array looks like. There is inner array called officers and I would want to loop through it and check if there is officer of a specific name and if so I would want to get the index key of the outer array.
'edges' =>
array (size=59)
0 =>
array (size=3)
'source' => int 0
'target' => int 12
'officers' =>
array (size=1)
0 => string 'PARKER, Thomas, Sir' (length=19)
1 =>
array (size=3)
'source' => int 0
'target' => int 19
'officers' =>
array (size=1)
0 => string 'STEVENS, Anne' (length=13)
So if I checked for STEVENS, Anne I would want to get key 1.
Here is code I found in a different question it works with 2d arrays but not with 3d array.
function array_search_inner ($array, $attr, $val, $strict = FALSE) {
// Error is input array is not an array
if (!is_array($array)) return FALSE;
// Loop the array
foreach ($array as $key => $inner) {
// Error if inner item is not an array (you may want to remove this line)
if (!is_array($inner)) return FALSE;
// Skip entries where search key is not present
if (!isset($inner[$attr])) continue;
if ($strict) {
// Strict typing
if ($inner[$attr] === $val) return $key;
} else {
// Loose typing
if ($inner[$attr] == $val) return $key;
}
}
// We didn't find it
return NULL;
}
Since there can be several index keys that fit the condition, it is reasonable to implement the function as a generator:
function getOfficerIndexKey($data, $officerName) {
foreach ($data['edges'] as $key => $value) {
in_array($officerName, $value['officers']) && (yield $key);
}
}
Now you can iterate over all found values:
foreach (getOfficerIndexKey($data, 'STEVENS, Anne') as $indexKey) {
// Do something
}
As well as just get the first found one:
getOfficerIndexKey($data, 'STEVENS, Anne')->current();
Related
I have a single key value array which I would like to loop through and create a seperate array from if certain conditions are met.
For example:
array(
1 => value
2.1 => value
2.2 => value
2.3 => value
2.4 => value
3 => value
)
My variable / condition I want to check is if the item in the array starts with a specific number. For example, if my var = 2, how can I create:
array(
2.1 => value
2.2 => value
2.3 => value
2.4 => value
)
Array filter will do exactly what you need, I just combined that with substr to check if the first char is a 2 and if it is it will return that in the array.
array_filter($array, function($k) {
return substr($k, 0, 1) == '2';
}, ARRAY_FILTER_USE_KEY);
Alternatively if you don't want to one line it you can create a function like the following to do it:
/**
* #param array $array
* #return array
*/
function filterArray(array $array): array
{
$finalData = [];
foreach($array as $key => $value) {
if(substr($key,0,1) == '2') {
$finalData[$key] = $value;
}
}
return $finalData;
}
I have a script where I want to get name of a column in array().
From API, I can get an array() with multiple values and I would like to get the name of a specific column.
I don't have columns' names, how do I get a list of them and fetch one by one?
Here, I want to get "573" only.
Array ( [success] => 1 [errors] => Array ( ) [data] => Array ( [Messages] => Array ( [573] => PHP is fun ) ) )
Thanks.
You just have to do a recursive iterator that will use itself to recurse or return a value based on the key match:
<?php
$arr = array(
'success' => 1,
'errors' => array(),
'data' => array(
'Messages' => array(
573 => 'PHP is fun'
)
)
);
function recurseIt($array,$find = false)
{
# Loop through array
foreach($array as $key => $value) {
# If the key is the same as the value
if($key == $find)
# Send back the value
return $value;
# If the value is an array
if(is_array($value)) {
# Use same array to recurse the array
$val = recurseIt($value,$find);
# If there is a value to return
if(!empty($val))
# Send it back
return $val;
}
}
}
# Note, if the key matches, could also be an array
echo recurseIt($arr,573);
Gives you:
PHP is fun
EDIT:
Presumably you have the value if you don't know the key, so this will return the key based on the search value:
function recurseIt($array,$find = false)
{
foreach($array as $key => $value) {
# If the key is the same as the value
if(!is_array($value) && ($value == $find))
# Send back the key name
return $key;
if(is_array($value)) {
$val = recurseIt($value,$find);
if(!empty($val))
return $val;
}
}
}
echo recurseIt($arr,'PHP is fun');
Gives you:
573
Now, if you don't know what the key name is and don't know the associated value would be, then the function doesn't know how to search. read_my_mind() is not yet in the PHP library so at that point you are pretty much out of luck.
I have an array of matches, each match has an ID and an array of users (from 2 to 4), each user is uniquely identified by it's own user_id. Example of the array:
array (size=2)
0 =>
array (size=2)
'id' => int 11268
'users' =>
array (size=2)
0 =>
array (size=1)
'user_id' => int 960781
1 =>
array (size=1)
'user_id' => int 960786
1 =>
array (size=2)
'id' => int 11267
'users' =>
array (size=2)
0 =>
array (size=1)
'user_id' => int 960783
1 =>
array (size=1)
'user_id' => int 902177
Now I want to add users details to the above array, so I do a query on the DB and I have this: (the row with id=n contains the details of user with user_id=n)
if ($res = $stmt->get_result()) { // it gets user details
while($row=$res->fetch_assoc()) {
foreach ($matches as &$match) {
foreach ($match['users'] as &$user) {
if($user['user_id']==$row['id']) {
$user['details']=$row;
}
}
}
}
}
This is working fine, but it's not the best way, because for each row I walk all the array. Do you have any idea how can I optimize this?
Thanks very much
You can simplify the problem by indexing the user arrays by userid. The code becomes a bit more complex now, but the computational complexity class is lower. If the new solution is really faster depends on the actual sizes of the individual arrays, so you'd have to measure both solutions with real-life-production-data to see what the fastest solution actually is.
<?php
function index_array_by($array, $key) {
$result = array();
foreach($array as &$value) {
$new_key = $value[$key];
$result[$new_key] = &$value;
}
return $result;
}
foreach($matches as &$match) {
$match['users'] = index_array_by($match['users'], "user_id");
}
if ($res = $stmt->get_result()) { // it gets user details
while($row=$res->fetch_assoc()) {
foreach ($matches as &$match) {
$user_id = $row['id'];
$match['users'][$user_id]['details'] = $row;
}
}
}
?>
I found this solution that require to scan the array only once, but I guess it uses more memory since I'm saving the rows into an array:
//Save the results in an array to later add to the matches array
if ($res = $stmt->get_result()) { //second get: it gets user details
while($row=$res->fetch_assoc()) {
$rows[$row['id']]=$row;
}
}
mysqli_free_result($res);
//Add the user details to the matches array
foreach ($matches as &$match) {
foreach ($match['users'] as &$user) {
$user['details']=$rows[$user['user_id']];
}
}
I have one array as below :
Array
(
[Sep] => Array
(
[Support Help Desk] => 24.67
[Development] => 7.74
[Consulting Services] => 4.04
)
[Oct] => Array
(
[Support Help Desk] => 14.38
[Business Activity] => 1.92
[Maintenance Tasks] => 1.00
[Development] => 2.11
)
)
and i want array like this :
Array
(
[Support Help Desk] => 24.67,14.38
[Development] => 7.74,2.11
[Consulting Services] => 4.04,0
[Business Activity] => 0,1.92
[Maintenance Tasks] => 0,1.00
)
I am using php with zend framework.
But i don't know what method should i use to get array like this ?
can anyone please guide me ?
-
Thanks in advance.
Third time lucky! I missed out on some subtleties in the question originally. Try the following code - it's a bit loopy but it should work for you.
I am assuming that your original array is called $data.
// first we need to 'normalise' or fill in the blanks in the contents of the sub array
// get a unique list of all the keys shared - doing it manually here
$keys = ['Support Help Desk', 'Business Activity', 'Maintenance Tasks', 'Development', 'Consulting Services'];
// create a default array with $keys, assigning 0 as the value of each
$default = array_fill_keys($keys, 0);
// next fill in the blanks...
// get the diff (missing keys) between the current element and the default array
// merge the missing key/value pairs
array_walk($data, function(&$month, $key, $default) {
$diff = array_diff_key($default, $month);
$month = array_merge($diff, $month);
}, $default);
// now the array is normalised
// flatten the array... where there are duplicate values for a key, and
// there will be in all cases now including default values
// a sub array is created
$merged = call_user_func_array('array_merge_recursive', $data);
// finally loop over the merged array
// and implode each array of values into a comma separated list
foreach ($merged as &$element) {
if (is_array($element)) {
$element = implode(', ', $element);
}
}
// done :)
var_dump($merged);
Yields:
array (size=5)
'Business Activity' => string '0, 1.92' (length=7)
'Maintenance Tasks' => string '0, 1' (length=4)
'Support Help Desk' => string '24.67, 14.38' (length=12)
'Development' => string '7.74, 2.11' (length=10)
'Consulting Services' => &string '4.04, 0' (length=7)
Hope this helps :)
EDIT
Live example at eval.in
Let's say your array is stored in $main_arr and result array is $result_arr.
$result_arr = array();
foreach ($main_arr as $month) {
foreach ($month as $key => $val) {
if (!isset($result_arr[$key])) {
$result_arr[$key] = array($val);
} else {
array_push($result_arr[$key], $val);
}
}
}
foreach ($result_arr as $key => $val) {
$result_arr[$key] = implode(', ', $val);
}
print_r($result_arr); //Final output.
My title is a bit confusing. I will try to explain better what I want to do.
I have an array with other arrays:
array (size=16)
0 =>
array (size=4)
'value' => string 'apple.png' (length=9)
'x' => int 3
'y' => int 4
'status' => boolean false
1 =>
array (size=4)
'value' => string 'apple.png' (length=9)
'x' => int 2
'y' => int 3
'status' => boolean false
2 =>
array (size=4)
'value' => string 'cake.png' (length=8)
'x' => int 3
'y' => int 1
'status' => boolean false
Then I have a form with hidden inputs:
'<input type="hidden" value="x:'.$i.';y:'.$j.'" name="coords"/>';
When the form is submitted I get the value and extract the coordinates. Then I do a loop.
foreach($this->mapBoard as $block)
{
if($block['x'] == $x && $block['y'] == $y)
{
$block['status'] = true;
return $block;
}
else
{
continue;
}
}
The main array is called 'mapBoard'. My question is how when I find the right array element, to change its value of the status key. And put it back in mapBoard.
Try,
foreach($this->mapBoard as $key => $block)
{
if($block['x'] == $x && $block['y'] == $y)
{
$this->mapBoard[$key]['status'] = true;
return $block;
}
else
{
continue;
}
}
PHP's foreach by default makes a copy of the array it is iterating on, so we will have to manually stuff data back in when modified.
Here is a simple tweak to your code to do it
// For arrays foreach will give us the loop iteration in `i` while using $i => $block
foreach($this->mapBoard as $i=>$block)
{
if($block['x'] == $x && $block['y'] == $y)
{
$block['status'] = true;
// we know i is the position, so stuff it back in
$this->mapBoard[$i] = $block;
return $block;
}
else
{
continue;
}
}
You can return array key in place of $block['status'] = true; , after that you update status according to array key.