PHP - Searching in multidimensional array - php

i'm in a lot of brain-pain, please advise. I have the following situation:
i have the next multidimensional array:
$numbers = array (
"one_digit" => array (1,2,3,4,5),
"two_digits" => array (20,21,22,23,24,25),
"three_digits" => array (301,302,303,304,304),
"mixed_digits" => array (9,29,309,1)
);
i need a way to search in the $numbers array for the following:
-- search if number 20 is in any $numbers array and echo where it is found
ex. $find1 = m_array_search("20", $numbers); echo "i've found the searched value in ".$find1." subarray of $numbers";
result: "i've found the searched value in two_digits subarray of $numbers"
-- search if number 1 is in any $numbers array and echo where it is found
ex. $find2 = m_array_search("1", $numbers); echo "i've found the searched value in ".$find2." subarray of $numbers";
result: "i've found the searched value in two_digits,mixed_digits subarray of $numbers"
thus function must be able to spot presence in one or many "subarrays". sorry if i've missued the term "subarray"
THANK YOU!!!

Simple solution using in_array function:
$search = 1;
$keys = [];
foreach ($numbers as $k => $v) {
if (is_array($v) && in_array($search, $v)) $keys[] = $k;
}
echo "I've found the searched value in ". implode(', ', $keys) ." subarray". ((count($keys) > 1)? "s":"") ." of \$numbers";
The output:
I've found the searched value in one_digit, mixed_digits subarrays of $numbers

Check this and let me know if it helps you .
<?php
function array_find_deep($array, $search, $keys = array())
{
foreach($array as $key => $value) {
if (is_array($value)) {
$sub = array_find_deep($value, $search, array_merge($keys, array($key)));
if (count($sub)) {
return $sub;
}
} elseif ($value === $search) {
return array_merge($keys, array($key));
}
}
return array();
}
$numbers = array (
"one_digit" => array (1,2,3,4,5),
"two_digits" => array (20,21,22,23,24,25),
"three_digits" => array (301,302,303,304,304),
"mixed_digits" => array (9,29,309,1)
);
var_dump(array_find_deep($numbers, 20));
var_dump(array_find_deep($numbers, 1));
var_dump(array_find_deep($numbers, 301));
var_dump(array_find_deep($numbers, 309));
?>
You can store the result in a variable like $result = array_find_deep($numbers, 20); and try echo $result[0] which will give the result that in which array it found the value.

You can try this with array_search() in a loop -
$numbers = array (
"one_digit" => array (1,2,3,4,5),
"two_digits" => array (20,21,22,23,24,25),
"three_digits" => array (301,302,303,304,304),
"mixed_digits" => array (9,29,309,1)
);
function search_value($array, $value)
{
$result = array();
foreach($array as $key => $sub) {
// check if element present in sub array
if(array_search($value, $sub) !== false) {
// store the key
$result[] = $key;
}
}
return $result;
}
var_dump(search_value($numbers, 1));
var_dump(search_value($numbers, 5));
Output
array(2) {
[0]=>
string(9) "one_digit"
[1]=>
string(12) "mixed_digits"
}
array(1) {
[0]=>
string(9) "one_digit"
}

Related

How to sort an Array based on value in PHP without breaking Array structure

I want to sort the array based on "match" index value as shown below:
Array
(
[0] => Array
(
[U] => Array
(
[user_id] => 10443
[match] => 100
)
)
)
This Array will be having match value like 25,50,75 etc.....
I tried below code but didn't worked :
function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
$sort_col = array();
foreach ($arr as $key=> $row) {
$sort_col[$key] = $row['U'][$col];
}
return array_multisort($sort_col, $dir, $arr);
}
$a_sl =$this->array_sort_by_column($a_sl, 'match');
where $a_sl contains array structure mentioned above.
How to sort this array based on match without breaking the Array structure.
I use the following code to sort arrays by subvalues:
function array_sort_subval($a, $subkey) {
if (!is_array($a) || count($a) == 0) {
return $a;
}
$i = 0; // Required to work around items with the same subkey value
foreach($a as $k=>$v) {
$b[$v[$subkey] . $i] = $v;
$i++;
}
ksort($b);
foreach($b as $key=>$val) {
$c[] = $val;
}
return $c;
}
To sort on deeper elements of your array, simply change the line
$b[$v[$subkey] . $i] = $v;
to get the deeper $subkey you want to sort on.

Build multidimensional array from keys

I can't seem to figure this out and I'm hoping someone has a magical recursive solution to this. I have a list of keys and basically I want to transform it into a nested array.
array('level1', 'level2', 'level3');
To
array(
'level1' => array(
'level2' => array(
'level3' // last key in array should be just a value
)
)
)
Much appreciation to anyone who can help!
Something like this should do the job:
function buildMultiDimensional(Array $arr)
{
// the first value will become a new key
$newKey = array_shift($arr);
if (empty($arr)) {
// this is where the recursion stops
return $newKey;
}
// and the recursion !!!
return array($newKey => buildMultiDimensional($arr));
}
$arr = array('level1', 'level2', 'level3', 'level4', 'level5');
var_dump(buildMultiDimensional($arr));
The result is what's expected:
array(1) {
["level1"]=>
array(1) {
["level2"]=>
array(1) {
["level3"]=>
array(1) {
["level4"]=>
string(6) "level5"
}
}
}
}
You don't need recursion. A single loop is fine with references.
<?php
//array to iterate
$array = array('level1', 'level2', 'level3');
//contains our entire array
$out = array();
//temp variable to store references as we go down.
$tmp = &$out;
//get the last value off the array
$last = array_pop($array);
//loop over the array
foreach($array as $level){
//make an array under the current level
$tmp[$level] = array();
//assign tmp to the new level
$tmp = &$tmp[$level];
}
//assign the last key as the value under the last key
$tmp = $last;
//display output
print_r($out);
example: http://codepad.viper-7.com/zATfyo
And without references, working in reverse:
<?php
//array to iterate
$array = array('level1', 'level2', 'level3');
//get the last value off the array
$out = array_pop($array);
//flip the array backwards
$array = array_reverse($array);
//loop over the array
foreach($array as $level){
$out = array($level=>$out);
}
//display output
print_r($out);
Example: http://codepad.viper-7.com/fgxeHO

Compare and replace values in array

I need compare 2 arrays , the first array have one order and can´t change , in the other array i have different values , the first array must compare his id with the id of the other array , and if the id it´s the same , take the value and replace for show all in the same order
For Example :
$array_1=array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2=array("4a-walking","2a-cats");
The Result in this case i want get it´s this :
"1a-dogs","2a-cats","3a-birds","4a-walking"
If the id in this case 4a it´s the same , that entry must be modificate and put the value of other array and stay all in the same order
I do this but no get work me :
for($fte=0;$fte<count($array_1);$fte++)
{
$exp_id_tmp=explode("-",$array_1[$fte]);
$cr_temp[]="".$exp_id_tmp[0]."";
}
for($ftt=0;$ftt<count($array_2);$ftt++)
{
$exp_id_targ=explode("-",$array_2[$ftt]);
$cr_target[]="".$exp_id_targ[0]."";
}
/// Here I tried use array_diff and others but no can get the results as i want
How i can do this for get this results ?
Maybe you could use the array_udiff_assoc() function with a callback
Here you go. It's not the cleanest code I've ever written.
Runnable example: http://3v4l.org/kUC3r
<?php
$array_1=array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2=array("4a-walking","2a-cats");
function getKeyStartingWith($array, $startVal){
foreach($array as $key => $val){
if(strpos($val, $startVal) === 0){
return $key;
}
}
return false;
}
function getMergedArray($array_1, $array_2){
$array_3 = array();
foreach($array_1 as $key => $val){
$startVal = substr($val, 0, 2);
$array_2_key = getKeyStartingWith($array_2, $startVal);
if($array_2_key !== false){
$array_3[$key] = $array_2[$array_2_key];
} else {
$array_3[$key] = $val;
}
}
return $array_3;
}
$array_1 = getMergedArray($array_1, $array_2);
print_r($array_1);
First split the 2 arrays into proper key and value pairs (key = 1a and value = dogs). Then try looping through the first array and for each of its keys check to see if it exists in the second array. If it does, replace the value from the second array in the first. And at the end your first array will contain the result you want.
Like so:
$array_1 = array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2 = array("4a-walking","2a-cats");
function splitArray ($arrayInput)
{
$arrayOutput = array();
foreach ($arrayInput as $element) {
$tempArray = explode('-', $element);
$arrayOutput[$tempArray[0]] = $tempArray[1];
}
return $arrayOutput;
}
$arraySplit1 = splitArray($array_1);
$arraySplit2 = splitArray($array_2);
foreach ($arraySplit1 as $key1 => $value1) {
if (array_key_exists($key1, $arraySplit2)) {
$arraySplit1[$key1] = $arraySplit2[$key1];
}
}
print_r($arraySplit1);
See it working here:
http://3v4l.org/2BrVI
$array_1=array("1a-dogs","2a-cats","3a-birds","4a-people");
$array_2=array("4a-walking","2a-cats");
function merge_array($arr1, $arr2) {
$arr_tmp1 = array();
foreach($arr1 as $val) {
list($key, $val) = explode('-', $val);
$arr_tmp1[$key] = $val;
}
foreach($arr2 as $val) {
list($key, $val) = explode('-', $val);
if(array_key_exists($key, $arr_tmp1))
$arr_tmp1[$key] = $val;
}
return $arr_tmp1;
}
$result = merge_array($array_1, $array_2);
echo '<pre>';
print_r($result);
echo '</pre>';
This short code works properly, you'll get this result:
Array
(
[1a] => dogs
[2a] => cats
[3a] => birds
[4a] => walking
)

PHP search multidimensional array with more than one result?

I found a way to search my multidimensional array and output the result and it works, however it only finds the first match and stops. If I have more than one match in the array I want to be able to show them all.
My array looks like this (the first layer of keys goes from 0, 1, 2 etc):
Array
(
[0] => Array
(
[mydevice] => blahblah
[ipadd] => 10.10.10.209
[portnum] => 16040
)
function searcharray($value, $key, $array) {
foreach ($array as $k => $val) {
if ($val[$key] == $value) {
return $k;
}
}
return null;
}
$myoutput = searcharray($ptn2, mydevice, $newresult);
I can then echo the results using something like $newresult[$myoutput][mydevice].
However if I have more than one entry in the array with a matching data in the 'mydevice' key it doesn't return them (just the first one).
That is because return breaks the function. You could use something like this:
function searcharray($value, $key, $array) {
$result = array();
foreach ($array as $k => $val) {
if ($val[$key] == $value) {
$result[] = $k;
}
}
return $result;
}
Now you will always get an array as result - empty if nothing was found. You can work with this like this e.g.
$mydevicekeys = searcharray($ptn2, "mydevice", $newresult);
foreach ($mydevicekeys as $mydevicekey) {
// work with $newresult[ $mydevicekey ]["mydevice"]
}
So add the results to an array :)
function searcharray($value, $key, $array) {
$res = array();
foreach ($array as $k => $val) {
if ($val[$key] == $value) {
$res[] = $key;
}
}
return $res;
}

Sorting arrays: second last

ksort ($votes);
foreach ($votes as $total => $contestant){
$ordervotes[]= $contestant;
}
echo "<li> And the winner is: {$ordervotes[4]}</li>";
echo "<li> And the loser is: {$ordervotes[0]}</li>";
echo "<li> {$ordervotes[1]} came second last</li>";
This works fine when none of the '$total's are the same, if they are the same i get an error code. I realise I could use the 'max/min' to get the first and last elements of the array, but how do i go about finding the second last?
Thank you
Joe
Why don't you try:
echo $votes[count($votes)-2];
You also don't need to populate another array with the same values - you can keep them in $votes. You might also want to look into sorting your array by value instead of by key (which I assume you're trying to do).
If you're expecting duplicate keys, you need to remodel the way you're storing your data. Consider using a multidimensional array:
$votes = array(
array('name'=>'John','vote'=>10),
array('name'=>'James','vote'=>11),
array('name'=>'Jimmy','vote'=>13),
);
You will be able to sort this array using this function and code:
// This function will sort your array
function aasort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
// Sort the array by the 'vote' key
aasort($votes,"vote");
// Echo out the name of the second-last person
echo $votes[count($votes)-2]['name'];
Use this:
function secondMax($arr) {
$max = $second = 0;
$maxKey = $secondKey = null;
foreach($arr as $key => $value) {
if($value > $max) {
$second = $max;
$secondKey = $maxKey;
$max = $value;
$maxKey = $key;
} elseif($value > $secondMax) {
$second = $value;
$secondKey = $key;
}
}
return array($secondKey, $second);
}
Usage:
$second = secondMax($votes);
You can retrieve it by using the function count:
$ordervotes[ (count($ordervotes)-2) ]
// the array starts with index 0, so (count($ordervotes)-1) is the last element
I don't understand what is in your $votes variable ... How could you have multiple contestants with the same votes (and so, with the same key).
I think there is a mistake here.
You $votes should be like this :
$votes = array(
'contestant 1' => 8,
'contestant 2' => 12,
'contestant 3' => 3
);
Then order the array : sort($votes)
Finaly, get the second last : $votes[count($votes) - 2];

Categories