need help in get values from array - php

Hi need help getting values from array
first i have get consecutive values from below array eg=>id:1,2 ignore if consecutive values doesn`t not exits
after getting values find the differences between the bids of consecutive values , then sum up all the values of bids(consecutive values) ??
$bidperpage = array([0]=>array(['id']=>1,['bid']='10',['page']='5'),
[1]=>array(['id']=>2,['bid']='15',['page']='5'),
[2]=>array(['id']=>9,['bid']='20',['page']='2'),
[3]=>array(['id']=>3,['bid']='30',['page']='7'),
[4]=>array(['id']=>4,['bid']='40',['page']='7'),
[5]=>array(['id']=>5,['bid']='50',['page']='9'),
[6]=>array(['id']=>6,['bid']='60',['page']='4'),
[7]=>array(['id']=>8,['bid']='70',['page']='4'));
function checkconsecutivevalue($array) {
$ret = array();
$temp = array();
foreach($array as $val) {
if(next($array) == ($val + 1))
$temp[] = $val;
else
if(count($temp) > 0) {
$temp[] = $val;
$ret[] = $temp[0].':'.end($temp);
$temp = array();
}
else
$ret[] = $val;
}
return $ret;
}

If nothing else, your array definition is a flat-out syntax error. It should be
$bidperpage = array(
0 => array('id' => 1, 'bid' => '10', 'page' => '5'),
etc...
);
Note the proper use of the => operator, and the LACK of [] braces.

The easiest way to do this, to my mind is using usort:
$bidperpage = array(array('id'=>1,'bid'=>'10','page'=>'5'),
array('id'=>2,'bid'=>'15','page'=>'5'),
array('id'=>9,'bid'=>'20','page'=>'2'),
array('id'=>3,'bid'=>'30','page'=>'7'),
array('id'=>4,'bid'=>'40','page'=>'7'),
array('id'=>5,'bid'=>'50','page'=>'9'),
array('id'=>11,'bid'=>'60','page'=>'q'),
array('id'=>8,'bid'=>'70','page'=>'4'));
//Sort function
function sortById($a,$b)
{
if ($a['id'] === $b['id'])
{
return 0;
}
return ($a['id'] > $b['id'] ? 1 : -1);
}
usort($bidperpage,'sortById');
More info: See the docsDo remember, I assumed the key id will always be pressent, if this is not the case, you might want to add an extra check to the callback function:
function sortById($a,$b)
{
if (!isset($a['id']) && !isset($b['id']))
{
return 0;
}
if (!isset($a['id']))
{
return 1;//move to end of array
}
if (!isset($b['id']))
{
return -1;
}
if ($a['id'] === $b['id'])
{
return 0;
}
return ($a['id'] > $b['id'] ? 1 : -1);
}
This function needn't be that verbose, but since I get the impression you haven't tried that much, I'll leave that up to you.

Related

Check if a value exists multidimensional array and return its key

I have an array, say
$updates = array();
$updates['U1'] = array('F1', 'F2', 'F5');
$updates['U2'] = array('F3');
$updates['U3'] = array('F3', 'F4');
I need search for a value say F5 so it should return the key U1.
And also if there is multiple occurrence of a value, should return the last key.
Eg. searching F3 should return U3 and not U2.
I have searched a lot and can't find a way. I am looking for a solution without using loops.
without using loop:
function findArrVal($arr = [], $param){
static $indx = 0;
if($indx == 0){
krsort($arr);
}
$keys = array_keys($arr);
$values = array_values($arr);
if( count($values) == $indx ){
return false;
} else if( is_array($values[$indx]) && in_array($param, $values[$indx])){
return $keys[$indx];
} else {
++$indx;
return findArrVal($arr, $param);
}
return FALSE;
}
using loop:
function findArrVal($arr = [], $param){
krsort($arr);
foreach($arr as $key => $ar){
if(is_array($ar) && in_array($param, $ar)){
return $key;
}
}
return FALSE;
}
findArrVal($updates,'F3');
krsort - sorts the array in reverse order. ( to find the value at first occurrence )
is_array to check if the child value is an array type.
in_array to find the item on the child array.
Maybe It's helpful for you.
function _getFindArrayKey(array $arr, $key)
{
if (array_key_exists($key, $arr)) {
return true;
}
// check arrays contained in this array
foreach ($arr as $element) {
if (is_array($element)) {
if (_getFindArrayKey($element, $key)) {
return true;
}
}
}
return false;
}

Round number up to closest value in array

I've created an array with 'maximum' values in.
$management = array(
'100' => '1',
'500' => '2',
'1000' => '3',
);
And created a loop to find the closest value, rounding it up.
$speed = 10;
$r= '';
sort($management);
foreach($management as $mgmt => $name) {
if($mgmt >= $speed) {
$r= $name;
}
}
$r= end($management);
So, where the $speed is 10, it should pick up the array key 100 and if it was 100 it should still pickup 100 but if the speed was 200, it would pickup 500
The above is picking up 500 when the $speed is 10 though.
Can anyone help please?
You have a couple of problems with your code. Firstly, the call to sort rewrites all the keys of the $management array which you are using for the comparison; you need to use ksort instead to sort by the keys instead of the values. Secondly, since the keys are in ascending order, once one is greater than the $speed value, they all will be, so you need to break from the loop once you find a higher value. Try this instead:
$r= '';
ksort($management);
foreach($management as $mgmt => $name) {
if($mgmt >= $speed) {
$r= $name;
break;
}
}
echo $r;
Demo on 3v4l.org
this is an example on how you can do it :
$array = array(1, 10, 100, 200, 400, 500, 1000);
public function getArrayRoundUp($array, $number) {
sort($array);
foreach ($array as $a) {
if ($a >= $number) return $a;
}
return end($array);
}
$value = 950;
$nearest = getArrayRoundUp($array, $value);
//the expect result will be 1000
echo $nearest;
Use the following function
function find(array $array, $search)
{
$last = null; // return value if $array array is empty
foreach ($array as $key => $value) {
if ($key >= $search) {
return $key; // found it, return quickly
}
$last = $key; // keep the last key thus far
}
return $last;
}
Tested and Working:-
echo find($management, 100); // Will result 100
echo find($management, 200); //Will result 500

Compare the keys and values of three arrays with "array_diff_ukey"

Can somebody explain, what is 1 and -1 in this code: ($a>$b)?1:-1; ?
I know the Array ( [c] => blue ) is returning because the key c is not exist in $a2 and key_compare_func need to return number smaller, equal or bigger then 0.
But I don't understand, how I get the Array ( [c] => blue ), when the key_compare_func returns 0, 1 and -1:
function myfunction($a,$b) {
if ($a === $b) {
return 0;
}
return ($a > $b) ? 1 : -1;
}
$a1=array("a"=>"red","b"=>"green","c"=>"blue");
$a2=array("a"=>"blue","b"=>"black","e"=>"blue");
$result=array_diff_ukey($a1,$a2,"myfunction");
As you can see in array-diff-ukey documentation the "key_compare_func" need to return number smaller, equal or bigger then 0. the numbers 1 and -1 are just example for this results.
In your case you can simply use strcmp as it return the same logic.
You have Array ( [c] => blue ) in the return because the key c is not exist in the $a2 array as it say:
Compares the keys from array1 against the keys from array2 and returns the difference. This function is like array_diff() except the comparison is done on the keys instead of the values.
Edited
Specifically in array-diff-ukey you only need the return 0 because that the way this function is decided the keys are the same so in your example you can define it as:
function myfunction($a,$b) {
if ($a === $b)
return 0;
return 1; // or -1 or 3 or -3 **just not 0**
}
Consider that as the logic behind array-diff-ukey:
array function array-diff-ukey($a1, $a2, $compareFunction) {
$arr = array(); // init empty array
foreach($a1 as $key1 => $value1) { // for each key in a1
$found = false;
foreach($a1 as $key2 => $value2) { //search for all keys in a2
if ($compareFunction($key1, $key2) == 0)
$found = true; // found a key with the same
}
if ($found === false) // add the element only if non is found
$arr[$key1] = $value1;
}
return $arr;
}
If ($a>$b) is true (right after the ?) - you return 1. else (right after the :) will return -1.
It's a short way of writing this:
if ($a>$b) {
return 1;
} else {
return -1;
}
It is the ternary operator in PHP. You can say it as shorthand If/Else. Here is an example:
/* most basic usage */
$var = 5;
$var_is_greater_than_two = ($var > 2 ? true : false); // if $var greater than 2
// return true
// else false
If it is being difficult for you to understand, you can change it with:
if ($a===$b)
{
return 0;
}
else if($a > $b)
{
return 1;
}
else
{
return -1;
}

PHP: Sort Multidimensional Array with Different Depth per element by Field

i have have got an array of the complexe sort to store my navigation (which is supposed to be changed by the user afterwards). I do not want to have the script only work with 3 levels of depth so I am looking for a nice and good way to sort this array by the position field.
$nav[1]=array(
'name'=>'home',
'position'=>'2',
children=>array(
[1]=array(
'name'=>'page2',
position=>'3'),
[2]=array(
'name'=>'page3',
'position'=>'1'),
[3]=array(
'name'=>'page4',
'position'=>'2')
)
$nav[2]=array(
'name'=>'Second level 1',
'position'=>'1'
);
I hope someone can help me, thanks for thinking about the problem.
Sort each children array recursively. For example:
function cmp($a, $b)
{
$ap = intval($a['position']);
$bp = intval($b['position']);
if ($ap == $bp) {
return 0;
}
return ($ap < $bp) ? -1 : 1;
}
function sort_menu(&$item)
{
if ($item['children']) {
foreach ($item['children'] as &$child) {
sort_menu($child);
}
usort($item['children'], "cmp");
}
}
$tmp = array('children' => $nav);
sort_menu($tmp);
$nav = $tmp['children'];
Here is an example of usort.
function yourSortFunction($a, $b)
{
if ($a['position'] == $b['position']) {
return 0;
}
return ($a['position'] < $b['position']) ? -1 : 1;
}
usort($nav, "yourSortFunction");'
You can call it in your $nav array in recursion in other function.

Checking if array is multidimensional or not?

What is the most efficient way to check if an array is a flat array
of primitive values or if it is a multidimensional array?
Is there any way to do this without actually looping through an
array and running is_array() on each of its elements?
Use count() twice; one time in default mode and one time in recursive mode. If the values match, the array is not multidimensional, as a multidimensional array would have a higher recursive count.
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
This option second value mode was added in PHP 4.2.0. From the PHP Docs:
If the optional mode parameter is set to COUNT_RECURSIVE (or 1), count() will recursively count the array. This is particularly useful for counting all the elements of a multidimensional array. count() does not detect infinite recursion.
However this method does not detect array(array()).
The short answer is no you can't do it without at least looping implicitly if the 'second dimension' could be anywhere. If it has to be in the first item, you'd just do
is_array($arr[0]);
But, the most efficient general way I could find is to use a foreach loop on the array, shortcircuiting whenever a hit is found (at least the implicit loop is better than the straight for()):
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
$c = array(1 => 'a',2 => 'b','foo' => array(1,array(2)));
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
function is_multi2($a) {
foreach ($a as $v) {
if (is_array($v)) return true;
}
return false;
}
function is_multi3($a) {
$c = count($a);
for ($i=0;$i<$c;$i++) {
if (is_array($a[$i])) return true;
}
return false;
}
$iters = 500000;
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi($a);
is_multi($b);
is_multi($c);
}
$end = microtime(true);
echo "is_multi took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi2($a);
is_multi2($b);
is_multi2($c);
}
$end = microtime(true);
echo "is_multi2 took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
is_multi3($a);
is_multi3($b);
is_multi3($c);
}
$end = microtime(true);
echo "is_multi3 took ".($end-$time)." seconds in $iters times\n";
?>
$ php multi.php
is_multi took 7.53565130424 seconds in 500000 times
is_multi2 took 4.56964588165 seconds in 500000 times
is_multi3 took 9.01706600189 seconds in 500000 times
Implicit looping, but we can't shortcircuit as soon as a match is found...
$ more multi.php
<?php
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
function is_multi($a) {
$rv = array_filter($a,'is_array');
if(count($rv)>0) return true;
return false;
}
var_dump(is_multi($a));
var_dump(is_multi($b));
?>
$ php multi.php
bool(true)
bool(false)
For PHP 4.2.0 or newer:
function is_multi($array) {
return (count($array) != count($array, 1));
}
I think this is the most straight forward way and it's state-of-the-art:
function is_multidimensional(array $array) {
return count($array) !== count($array, COUNT_RECURSIVE);
}
After PHP 7 you could simply do:
public function is_multi(array $array):bool
{
return is_array($array[array_key_first($array)]);
}
You could look check is_array() on the first element, under the assumption that if the first element of an array is an array, then the rest of them are too.
I think you will find that this function is the simplest, most efficient, and fastest way.
function isMultiArray($a){
foreach($a as $v) if(is_array($v)) return TRUE;
return FALSE;
}
You can test it like this:
$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
echo isMultiArray($a) ? 'is multi':'is not multi';
echo '<br />';
echo isMultiArray($b) ? 'is multi':'is not multi';
Don't use COUNT_RECURSIVE
click this site for know why
use rsort and then use isset
function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
Even this works
is_array(current($array));
If false its a single dimension array if true its a multi dimension array.
current will give you the first element of your array and check if the first element is an array or not by is_array function.
You can also do a simple check like this:
$array = array('yo'=>'dream', 'mydear'=> array('anotherYo'=>'dream'));
$array1 = array('yo'=>'dream', 'mydear'=> 'not_array');
function is_multi_dimensional($array){
$flag = 0;
while(list($k,$value)=each($array)){
if(is_array($value))
$flag = 1;
}
return $flag;
}
echo is_multi_dimensional($array); // returns 1
echo is_multi_dimensional($array1); // returns 0
I think this one is classy (props to another user I don't know his username):
static public function isMulti($array)
{
$result = array_unique(array_map("gettype",$array));
return count($result) == 1 && array_shift($result) == "array";
}
In my case. I stuck in vary strange condition.
1st case = array("data"=> "name");
2nd case = array("data"=> array("name"=>"username","fname"=>"fname"));
But if data has array instead of value then sizeof() or count() function not work for this condition. Then i create custom function to check.
If first index of array have value then it return "only value"
But if index have array instead of value then it return "has array"
I use this way
function is_multi($a) {
foreach ($a as $v) {
if (is_array($v))
{
return "has array";
break;
}
break;
}
return 'only value';
}
Special thanks to Vinko Vrsalovic
Its as simple as
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
This function will return int number of array dimensions (stolen from here).
function countdim($array)
{
if (is_array(reset($array)))
$return = countdim(reset($array)) + 1;
else
$return = 1;
return $return;
}
Try as follows
if (count($arrayList) != count($arrayList, COUNT_RECURSIVE))
{
echo 'arrayList is multidimensional';
}else{
echo 'arrayList is no multidimensional';
}
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);
Here is a nice one liner. It iterates over every key to check if the value at that key is an array. This will ensure true

Categories