I have a question
So I have this array :
Array
(
[2016] => Array
(
[23] => Array
(
[total_auctions] => 0
[total_price] => 0
)
[22] => Array
(
[total_auctions] => 0
[total_price] => 0
)
[21] => Array
(
[total_auctions] => 0
[total_price] => 0
)
[20] => Array
(
[total_auctions] => 0
[total_price] => 0
)
)
I want to sort recursive by key. So I create the methode :
public function sortNestedArrayAssoc($a)
{
if (!is_array($a)) {
return false;
}
ksort($a);
foreach ($a as $k=>$v) {
$this->sortNestedArrayAssoc($a[$k]);
}
return true;
}
But I get the same result, the array with the key 23 is the first and I don' really understand where is the problem. Can you help me please ? Thx in advance and sorry for my english
As John Stirling mentioned, something you could do would be to pass your arguments by reference. You can do this by using the & operator in your method argument. The syntax for that would be (with the only change being the first line):
public function sortNestedArrayAssoc(&$a)
{
if (!is_array($a)) {
return false;
}
ksort($a);
foreach ($a as $k=>$v) {
$this->sortNestedArrayAssoc($a[$k]);
}
return true;
}
This means that you are then passing the variable into your function and modifying it directly instead of what PHP does normally which is pass a copy of the variable into your function. ksort is an example of a function that uses a pass by reference in its function definition.
If you were strongly against using pass by reference, you'd have to modify your code to return your variable/array to the calling scope where you then update your array.
public function sortNestedArrayAssoc($a)
{
if (is_array($a)) {
ksort($a);
foreach ($a as $k=>$v) {
$a[$k] = $this->sortNestedArrayAssoc($v);
}
}
return $a;
}
Related
i want to get specific key with specific condition with indexing 0,1,2 from multidimensional array using array function only.
using forloop it is getting but i want it using array function for code optimization
my input code like:
Array
(
[0] => Array
(
[device_token] => 1324
[device_type] => 0
)
[1] => Array
(
[device_token] => 2546
[device_type] => 1
)
[2] => Array
(
[device_token] => 13241
[device_type] => 0
)
[3] => Array
(
[device_token] => 12345
[device_type] => 1
)
)
and i want only device_token which have device_type=0 with following format like :
Array
(
[0] => 1324,
[1] => 13241,
)
i am trying following code:
$ios_token = array_map(function($r) {
return $r['device_token'];
}
this give me device token of all.
array_filter should do it for you :
http://php.net/manual/en/function.array-filter.php
$ios_token = array_filter($myArray, function($item) {
return $item['device_type'] == 0;
});
It iterates over each value and if the callback function returns true, the current value of the array is returned.
Then you could pass your variable in an array_map function like you did :
$ios_token = array_map(function($item){
return $item['device_token'];
}, $ios_token);
And if you want to group everything :
$ios_token = array_map(function($item){
return $item['device_token'];
}, array_filter($myArray,
function($item) {
return $item['device_type'] == 0;
}
));
array_map() function gives you more possibilities with arrays.
func_array_map
function myfunction($v)
{
if ($v['device_type']==0)
{
return $v['device_token'];
}
return null;
}
$a=array(...) // your array here
print_r(array_values(array_filter(array_map("myfunction",$a))));
Here you need array_reduce:
$ios_token = array_reduce(
$your_array,
function($t, $v) {
if ($v['device_type'] == 0)
$t[] = $v['device_token'];
return $t;
},
array()
);
Try laconic solution with array_walk:
// assuming $arr is your main array
$result = [];
array_walk($arr, function($v) use(&$result){
if ($v['device_type'] == 0) $result[] = $v['device_token'];
});
var_dump($result);
I have an array that has multiple arrays inside it. I am trying to arrange those arrays from the amount of greatest to least new_sales. Here is the example of the array which goes on for about 40 arrays:
Array
(
[0] => Array
(
[Tech] => Array
(
[first_name] => Anthony
[last_name] => Bisignano
)
[0] => Array
(
[new_sales] => 21
[upgrades] => 2
)
)
[1] => Array
(
[Tech] => Array
(
[first_name] => Arnold
[last_name] => Ybanez
)
[0] => Array
(
[new_sales] => 5
[upgrades] => 0
)
)
The function I am trying to use is the following:
function aasort (&$techs, $key) {
$sorter=array();
$ret=array();
reset($techs);
foreach ($techs as $ii => $va) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$techs[$ii];
}
$techs=$ret;
}
aasort($test,"new_sales");
AM I using this function wrong or is there another approach I should be taking?
There are sorting functions in PHP that support user-defined comparison methods. Code like this should help you get started with that.
function cmp($a, $b)
{
if ($a[0]['new_sales'] == $b[0]['new_sales']) {
return 0;
}
return ($a[0]['new_sales'] < $b[0]['new_sales']);
}
usort($data, "cmp");
In this case you probably want to use usort() such that you can define your sorting logic.
So something like this:
usort($array, function($a, $b) {
if ($a[0]['new_sales'] > $b[0]['new_sales']) {
return -1; // note we use -1 here because we want a reverse sort
} else if ($a[0]['new_sales'] < $b[0]['new_sales']) {
return 1;
} else {
return 0;
}
});
I'm fetching some JSON from flickrs API. My problem is that the exif data is in different order depending on the camera. So I can't hard-code an array number to get, for instance, the camera model below. Does PHP have any built in methods to search through associative array values and return the matching arrays? In my example below I would like to search for the [label] => Model and get [_content] => NIKON D5100.
Please let me know if you want me to elaborate.
print_r($exif['photo']['exif']);
Result:
Array
(
[0] => Array
(
[tagspace] => IFD0
[tagspaceid] => 0
[tag] => Make
[label] => Make
[raw] => Array
(
[_content] => NIKON CORPORATION
)
)
[1] => Array
(
[tagspace] => IFD0
[tagspaceid] => 0
[tag] => Model
[label] => Model
[raw] => Array
(
[_content] => NIKON D5100
)
)
[2] => Array
(
[tagspace] => IFD0
[tagspaceid] => 0
[tag] => XResolution
[label] => X-Resolution
[raw] => Array
(
[_content] => 240
)
[clean] => Array
(
[_content] => 240 dpi
)
)
$key = array_search('model', array_column($data, 'label'));
In more recent versions of PHP, specifically PHP 5 >= 5.5.0, the function above will work.
To my knowledge there is no such function. There is array_search, but it doesn't quite do what you want.
I think the easiest way would be to write a loop yourself.
function search_exif($exif, $field)
{
foreach ($exif as $data)
{
if ($data['label'] == $field)
return $data['raw']['_content'];
}
}
$camera = search_exif($exif['photo']['exif'], 'model');
$key = array_search('Model', array_map(function($data) {return $data['label'];}, $exif))
The array_map() function sends each value of an array to a user-made function, and returns an array with new values, given by the user-made function. In this case we are returning the label.
The array_search() function search an array for a value and returns the key. (in this case we are searching the returned array from array_map for the label value 'Model')
This would be fairly trivial to implement:
$model = '';
foreach ($exif['photo']['exif'] as $data) {
if ($data['label'] == 'Model') {
$model = $data['raw']['_content'];
break;
}
}
foreach($exif['photo']['exif'] as $row) {
foreach ($row as $k => $v) {
if ($k == "label" AND $v == "Model")
$needle[] = $row["raw"];
}
}
print_r($needle);
The following function, searches in an associative array both for string values and values inside other arrays. For example , given the following array
$array= [ "one" => ["a","b"],
"two" => "c" ];
the following function can find both a,b and c as well
function search_assoc($value, $array){
$result = false;
foreach ( $array as $el){
if (!is_array($el)){
$result = $result||($el==$value);
}
else if (in_array($value,$el))
$result= $result||true;
else $result= $result||false;
}
return $result;
}
$data = [
["name"=>"mostafa","email"=>"mostafa#gmail.com"],
["name"=>"ali","email"=>"ali#gmail.com"],
["name"=>"nader","email"=>"nader#gmail.com"]];
chekFromItem($data,"ali");
function chekFromItem($items,$keyToSearch)
{
$check = false;
foreach($items as $item)
{
foreach($item as $key)
{
if($key == $keyToSearch)
{
$check = true;
}
}
if($check == true)
{break;}
}
return $check;}
As far as I know , PHP does not have in built-in search function for multidimensional array. It has only for indexed and associative array. Therefore you have to write your own search function!!
I have a multidimensional array in PHP and want to be able to search through it and find all values that are objects.
The reason I want to do this is so that when an object is found I can replace it with an array by calling an output() method on it. The output() method uses get_object_vars() to turn itself into an array, which it then returns.
Here's an example which achieves what I want manually (but only with 2 levels of depth):
// First level search...
foreach($array as $k => $v) {
// Check if it's an array.
if (is_array($v)) {
// Second level search...
foreach($v as $k2 => $v2) {
// If it's an object - convert it!
if (is_object($v2)) {
$array[$k][$k2] = $array[$k][$k2]->output();
}
}
}
// If it's an object - convert it!
if (is_object($v)) {
$array[$k] = $array[$k]->output();
}
}
Tim Cooper's answer is wrong because the function must have a parameter that is passed by reference and not by value.
php > class Foo { public function output() { return "this was an object"; } }
php > $a = array( 1 => array( 2 => array( 'foo', 'red', 1, new Foo() ) ) );
php > array_walk_recursive( $a, function( $item, $key ) {
if ( is_object( $item ) ) {
$item = $item->output();
}
} );
php > print_r( $a );
Array
(
[1] => Array
(
[2] => Array
(
[0] => foo
[1] => red
[2] => 1
[3] => Foo Object
(
)
)
)
)
Versus passing by reference:
php > array_walk_recursive( $a, function( &$item, $key ) {
if ( is_object( $item ) ) {
$item = $item->output();
}
} );
php > print_r( $a );
Array
(
[1] => Array
(
[2] => Array
(
[0] => foo
[1] => red
[2] => 1
[3] => this was an object
)
)
)
You just need a recursive function:
function objects_to_arrays_recursive (&$array) {
foreach ($array as &$member) {
if (is_object($member)) {
$member = $member->output();
}
if (is_array($member)) {
objects_to_arrays_recursive($member);
}
}
}
This will call the output() method of every object and store the result in the key that originally held the object.
Caveats:
This will loop the objects once they have been converted and also convert child objects. You may not want to do this, particularly if you have circular references as this would result in an infinte loop. It can be avoided just by changing the 2 ifs into if / elseif.
This does not check whether a given object has an output() method to call. You should probably add an is_a()/instanceof check.
This function takes its argument by reference, which means the input array will be modified. If you need to keep the original array intact, you will need to make a copy of it first.
i've got a PHP script where i rearange a multidimensional array with the use of the usort()-function.
this is a sample array (print_r-output) of array $arr
Array
(
[3] => Array
(
[name] => Bjudningen
[grade] => 5
[grade_type] => calculated
[orgname] => LInvitation
[id] => 13975
)
[0] => Array
(
[name] => Coeur fidèle
[grade] => 3
[grade_type] => calculated
[orgname] => Coeur fidèle
[id] => 8075
)
[2] => Array
(
[name] => Dawsonpatrullen
[grade] => 5
[grade_type] => calculated
[orgname] => The Dawson Patrol
[id] => 13083
)
)
And this is my PHP script
function sort_movies($arr,$val){
function cmp($x, $y)
{
if ( $x[$val] == $y[$val] )
return 0;
else if ( $x[$val] < $y[$val] )
return -1;
else
return 1;
}
usort($arr, 'cmp');
return $arr;
}
$sorted = sort_movies($arr,"grade");
I want to be able to sort the array on different subkeys (i.e. name, grade,id), but it doesn't work the way i do it above. however if i change $val in the sort movies function to the value "grade" it does work, so for some reason it won't allow me to send in a vaiable as the sort parameter.
what is it i'm doing wrong?
May be try this by send index of subkey i.e. grade instead of name of subkey .
With 5.3 you can do it like this:
function create_sort($key)
{
return function($x,$y) use($key)
{
return $x[$key] - $y[$key];
};
}
$sorter = create_sort('name');
usort($arr, $sorter);
The problem is that $val is only available within the scope of the function sort_movies(), not in the scope of cmp(). You need to just declare it as global. This will pull it into scope so you can use it within the cmp() function.
function sort_movies($arr,$val){
function cmp($x, $y)
{
global $val; // <---------------------------------
if ( $x[$val] == $y[$val] )
return 0;
else if ( $x[$val] < $y[$val] )
return -1;
else
return 1;
}
usort($arr, 'cmp');
return $arr;
}
$sorted = sort_movies($arr,"grade");
http://php.net/manual/en/language.variables.scope.php