I have an array. It' looks like:
$arr = [
'0' => ['id'=>9, 'q'=>'motor', 'pos'=>1],
'1' => ['id'=>10, 'q'=>'NULL', 'pos'=>0],
'2' => ['id'=>7, 'q'=>'motor', 'pos'=>2],
'3' => ['id'=>8, 'q'=>'NULL', 'pos'=>0],
'4' => ['id'=>11, 'q'=>'motor','pos'=>3],
'5' => ['id'=>11, 'q'=>'exhaust','pos'=>1]
];
How can I sort the data above to make it looks like (if q='motor' is inside search string):
$arr = [
'0' => ['id'=>9, 'q'=>'motor', 'pos'=>1],
'2' => ['id'=>7, 'q'=>'motor', 'pos'=>2],
'4' => ['id'=>11, 'q'=>'motor','pos'=>3],
'1' => ['id'=>10, 'q'=>'NULL', 'pos'=>0],
'3' => ['id'=>8, 'q'=>'NULL', 'pos'=>0],
'5' => ['id'=>11, 'q'=>'exhaust','pos'=>1]
];
So:
function custom_sort($input_query, $arr) {
foreach($arr as $key=>$row) {
if (strpos($input_query, $row['q'])) {
... How to Sort By Pos?
}
}
}
Thanks!
Updated (question/answer)
p.s: I'm trying to use custom variable as input: $q
usort($arr, function($a, $b) use ($q) {
if ($a['q'] == $q) {
if($b['q'] == $q) {
return ($a['pos'] > $b['pos']) ? 1 : -1;
}
return -1;
}
if ($b['q'] == $q) {
return 1;
}
return 0;
});
And the function stop working. How can I solve this?
Here's a usort that handles your requirements, wrapped in a function that transforms the array in place:
Items with q key containing $query will be placed at the front of the array.
Items with q key containing $query will be sorted ascending by their pos value.
Everything else will be sorted by its pos value.
function custom_sort($query, &$arr) {
usort($arr, function($a, $b) use ($query) {
$in_a = strpos($a['q'], $query) !== false;
$in_b = strpos($b['q'], $query) !== false;
if ($in_a && !$in_b) {
return -1;
}
if (!$in_a && $in_b) {
return 1;
}
return $a['pos'] - $b['pos'];
});
}
custom_sort("motor", $arr);
You can use usort
usort($arr, function($a, $b) {
if ($a['q'] == 'motor') {
if($b['q'] == 'motor') {
return ($a['pos'] > $b['pos']) ? 1 : -1;
}
return -1;
}
if ($b['q'] == 'motor') {
return 1;
}
return 0;
});
If you need a different order, just change the function to match your needs.
U sort would help you here
usort( $arr, function ( $a, $b ) {
if ( $a['q'] === $b['q'] ) {
return $a['pos'] < $b['pos'] ? -1 : 1;
}
if ( $a['q'] === 'motor' ) {
return -1;
}
if ( $b['q'] === 'motor' ) {
return 1;
}
return 0;
} );
Related
When I am adding same unit of number in "num". eg(0-9). It is sorting my array. But if any of the "num" value contains a different unit of digits, the sorting fails. eg(4,7,2,1) this will work. (7,12,76,2) this will fail.
$stack = array(array("Price" => $op,"num" => $noi),
array("Price" => $op1,"num" => $noi1),
array("Price" => $op2,"num" => $noi2),
array("Price" => $op3,"num" => $noi3));
function cmp($a, $b)
{
return strcmp($a["num"], $b["num"]);
}
usort($stack, "cmp");
Try this for comparison of numbers
function cmp($a, $b) {
if ($a['num'] == $b['num']) {
return 0;
}
return ($a['num'] < $b['num']) ? -1 : 1;
}
It is taken straight out of the PHP manual on usort, and modified for your array.
array
0 =>
array
'point' => string '2'
1 =>
array
'point' => string '4'
2 =>
array
'point' => string '1'
I need checking values of 'point' in above array, if all values of 'point' is '4' it will return true as below array.
array
0 =>
array
'point' => string '4'
1 =>
array
'point' => string '4'
2 =>
array
'point' => string '4'
You just need to use 2 statements fomr PHP. if and for.
I used following script to test it (you can choose one of the loops(for or foreach))
$test = array(array('point' => 4), array('point' => 4));
function checkArrayForPointValue($array, $expectedValue)
{
$ok = true;
for ($i = 0; $i < count($array); $i++) {
if ($array[$i]['point'] != $expectedValue) {
$ok = false;
break;
}
}
// choose one of them
foreach ($array as $element) {
if ($element['point'] != $expectedValue) {
$ok = false;
break;
}
}
return $ok;
}
print(checkArrayForPointValue($test, '4') ? 'yay' : 'not yay');
Compare each value in a foreach :
function arrayComparePoint($array) {
$valueCompare = $array[0]['point'];
foreach ($array as $arrayPoint) {
foreach ($arrayPoint as $point) {
if ($valueCompare != $point) {
return false;
}
}
}
return true;
}
Simply use as
function checkArray($myArray) {
$result = array_unique(array_column($myArray, 'point'));
return (count($result) == 1 && $result[0] == '4') ? "true" : "false";
}
echo checkArray($myArray);
I have following array
Array
(
[0] => Array
(
[data] => PHP
[attribs] => Array
(
)
[xml_base] =>
[xml_base_explicit] =>
[xml_lang] =>
)
[1] => Array
(
[data] => Wordpress
[attribs] => Array
(
)
[xml_base] =>
[xml_base_explicit] =>
[xml_lang] =>
)
)
one varialbe like $var = 'Php, Joomla';
I have tried following but not working
$key = in_multiarray('PHP', $array,"data");
function in_multiarray($elem, $array,$field)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if($array[$bottom][$field] == $elem)
return true;
else
if(is_array($array[$bottom][$field]))
if(in_multiarray($elem, ($array[$bottom][$field])))
return true;
$bottom++;
}
return false;
}
so want to check if any value in $var is exists in array(case insensitive)
How can i do it without loop?
This should work for you:
(Put a few comments in the code the explain whats goning on)
<?php
//Array to search in
$array = array(
array(
"data" => "PHP",
"attribs" => array(),
"xml_base" => "",
"xml_base_explicit" => "",
"xml_lang" => ""
),
array(
"data" => "Wordpress",
"attribs" => array(),
"xml_base" => "",
"xml_base_explicit" => "",
"xml_lang" => "Joomla"
)
);
//Values to search
$var = "Php, Joomla";
//trim and strtolower all search values and put them in a array
$search = array_map(function($value) {
return trim(strtolower($value));
}, explode(",", $var));
//function to put all non array values into lowercase
function tolower($value) {
if(is_array($value))
return array_map("tolower", $value);
else
return strtolower($value);
}
//Search needle in haystack
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
//Search ever value in array
foreach($search as $value) {
if(in_array_r($value, array_map("tolower", array_values($array))))
echo $value . " found<br />";
}
?>
Output:
php found
joomla found
to my understanding , you are trying to pass the string ex : 'php' and the key : 'data' of the element .
so your key can hold a single value or an array .
$key = in_multiarray("php", $array,"data");
var_dump($key);
function in_multiarray($elem, $array,$field)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if(is_array($array[$bottom][$field]))
{
foreach($array[$bottom][$field] as $value)
{
if(strtolower(trim($value)) == strtolower(trim($elem)))
{
return true;
}
}
}
else if(strtolower(trim($array[$bottom][$field])) == strtolower(trim($elem)))
{
return true;
}
$bottom++;
}
return false;
}
Ok, so I have this array :-
0 =>
array (size=2)
'receiver_telmob' => string '0707105396' (length=10)
0 => string '0707105396' (length=10)
1 =>
array (size=2)
'receiver_telmob' => string '0704671668' (length=10)
0 => string '0704671668' (length=10)
2 =>
array (size=2)
'receiver_telmob' => string '0707333311' (length=10)
0 => string '0707333311' (length=10)
And I'm trying to search in this array using in_array. But, I never get any true value.
Here's what I'm trying to do:-
$searchnumber = '0707333311';
if(in_array($searchnumber,$arrayAbove))
{
//do something
}
But the if always results a false output. I guess that I'm not using the in_array correctly here. What should I correct to make it work?
Thanks.
$array = array(
"0" => array(
"receiver_telmob" => "0707105396",
"0" => "0707105396"
),
"1" => array(
"receiver_telmob" => "0704671668",
"0" => "0704671668"
),
"2" => array(
"receiver_telmob" => "0707333311",
"0" => "0707333311"
)
);
$searchnumber = "0707333311";
foreach($array as $v) {
if ($v['receiver_telmob'] == $searchnumber) {
$found = true;
}
}
echo (isset($found) ? 'search success' : 'search failed');
in_array() doesn't work with multi-dimensional arrays. You need something like this -
function in_multi_array($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_multi_array($needle, $item, $strict))) {
return true;
}
}
return false;
}
Then you could do this -
$searchnumber = '0707333311';
if(in_multi_array($searchnumber,$arrayAbove))
{
//do something
}
You can't use in_array for multidimensional arrays!
But this function should work for you:
<?php
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
?>
Then you can use it like this:
echo in_array_r("0707333311", $arrayAbove) ? 'true(found)' : 'false(not found)';
You would have to use in_array for each sub array.
So if you have a 1 dimensional array like
[1,4,43,2,5,4] you could call in_array but when you have multidimensional you have to iterate over the top dimension and call in_array
for($i = 0;$i < arr.count(); $i++){
if(in_array($searchnum, $arr[$i]){
//do something
}
}
NOTE: the example above only works for 2d arrays just to demonstrate what I was talking about
Try this:
function in_array_recursive($needle, $haystack) {
foreach($haystack as $item) {
if ($needle = $item || is_array($item) && in_array_recursive($needle, $item))
return true;
}
}
return false;
}
$searchnumber = '0707333311';
if(in_array_recursive($searchnumber,$arrayAbove))
{
//do something
}
I've tried this with usort, but I didn't succeed.
I've the following array:
array(
[0] => array(
'date' => '3:6:2012'
),
[1] => array(
'date' => '5:5:2012'
),
[2] => array(
'date' => '20:12:2011'
)
)
The date is in d:m:yyyy format, so no leading zero's.
I want to sort the array to get this:
array(
[0] => array(
'date' => '20:12:2011'
),
[1] => array(
'date' => '5:5:2012'
),
[2] => array(
'date' => '3:6:2012'
)
)
I've tried it this way:
function cmp($a, $b) {
if($a['date'] = $b['date']) {
return 0;
}
$partsa = explode(":", $a['date']);
$partsb = explode(":", $b['date']);
$daya = $partsa[0];
$montha = $partsa[1];
$yeara = $partsa[2];
$dayb = $partsb[0];
$monthb = $partsb[1];
$yearb = $partsb[2];
if($yeara < $yearb) {
return -1;
} elseif($yeara > $yearb) {
return 1;
} elseif($yeara == $yearb) {
if($montha < $monthb) {
return -1;
} elseif($montha > $monthb) {
return 1;
} elseif($montha == $monthb) {
if($daya < $dayb) {
return -1;
} elseif($daya > $dayb) {
return 1;
} elseif($daya == $dayb) {
return 0;
}
}
}
}
but this doesn't give good results with usort...
How to do this?
You can create a temporary array with normalized dates (yyyymmdd), then use array_multisort:
$arr = array(
array(
'date' => '3:6:2012'
),
array(
'date' => '5:5:2012'
),
array(
'date' => '20:12:2011'
),
array(
'foo' => 'no date here'
),
);
foreach($arr as $key=>$row) {
if(isset($row['date'])) {
$date = explode(':',$row['date']);
$date = $date[2] . str_pad($date[1],2,'0',STR_PAD_LEFT) . str_pad($date[0],2,'0',STR_PAD_LEFT);
$sort_arr[$key] = $date;
} else {
$sort_arr[$key] = null;
}
}
array_multisort($sort_arr, SORT_ASC, $arr);
print_r($arr);
PHP offers the function strcmp, that's doing the comparing stuff for us. In order to compare the dates correctly, we create timestamp out of it.
But at first we need to parse the string: exploding by : and finally throwing them to mktime.
function cmp($a, $b) {
$a = explode(':', $a['date']);
$a = mktime(0, 0, 0, intval($a[1]), intval($a[0]), intval($a[2]));
$b = explode(':', $b['date']);
$b = mktime(0, 0, 0, intval($b[1]), intval($b[0]), intval($b[2]));
return strcmp($a, $b);
}
Note: The first three arguments of mktime are hours, minutes and seconds and can be ignored in this scenario.
First, make them dates (normal, php-readable dates):
foreach($array as $innerarray){
foreach($innerarray as $key=>$value){
$date = explode(":", $value);
$date = date($date[2]."/".$date[1]."/".$date[0]);
$array[$innerarray][$key] = $date;
}
}
After this, you can sort them with the following function:
function sort_bydate($a, $b) {
return strnatcmp($a['date'], $b['date']);
}
// sort by date
usort($data, 'sort_bydate');
This should do the trick.
By the way, I would advise to not use arrays in arrays, because it is useless in your case.