How to go a level up in an array? - php

I want would like to get the parent node of the array below, but I don't find a way to easily do this.
Normally for getting the id, I would do this in PHP:
echo $output['posts']['11']['id'];
But how can I get to the parent node "11" when I get the value of "id" passed from a $_GET/$_POST/$_REQUEST? (ie. $output['posts']['11'][$_GET[id]])
Array
(
[posts] => Array
(
[11] => Array
(
[id] => 482
[time] => 2011-10-03 11:26:36
[subject] => Test
[body] =>
[page] => Array
(
[id] => 472
[title] => News
)
[picture] => Array
(
[0] => link/32/8/482/0/picture_2.jpg
[1] => link/32/8/482/1/picture_2.jpg
[2] => link/32/8/482/2/picture_2.jpg
[3] => link/32/8/482/3/picture_2.jpg
)
)
)
)

$parent = null;
foreach ($array['posts'] as $key => $node) {
if ($node['id'] == $_GET['id']) {
echo "found node at key $key";
$parent = $node;
break;
}
}
if (!$parent) {
echo 'no such id';
}
Or possibly:
$parent = current(array_filter($array['posts'], function ($i) { return $i['id'] == $_GET['id']; }))
How this should work exactly depends on your array structure though. If you have nested arrays you may need a function that does something like the above recursively.

array_keys($output['posts']);
will give you all keys within the posts array, see http://php.net/manual/en/function.array-keys.php

you could try with something like:
foreach ($posts as $post){
foreach( $items as $item){
if ( $item['id'] == [$_GET[id] ){
// here, the $post is referring the parent of current item
}
}
}

I don't think it is possible while an array of array is not a DOM or any tree structure. In an array you can store any reference. but you can not naturally refer to an array containing a reference.

Check rolfs example for array_filter at php manual http://www.php.net/manual/en/function.array-filter.php#100813
So you could do it like this
$filtered = array_filter($output, function ($element) use ($_GET["id"]) { return ($element["id"] == $_GET["id"]); } );
$parent = array_pop($filtered);

Related

Array unique values PHP

I want to find the Unique values by username:
so the resulting array would be [0] =>JakeP, [1]=>TomC
My code currently works, but I was wondering is there a better way to accomplish this task with less loops, or using array_unique function?
Array
(
[0] => Array
(
[ID] => 3
[Username] => TomC
[Project_Name] => Inventory
)
[1] => Array
(
[ID] => 4
[Username] => JakeP
[Project_Name] => Inventory
)
[2] => Array
(
[ID] => 2
[Username] => TomC
[Project_Name] => Stocks
)
[3] => Array
(
[ID] => 1
[Username] => Tomc
[Project_Name] => Stocks
)
)
My code which works is :
$names_filter = array();
foreach($latest_projects as $project)
{
if(empty($names_filter))
{
$names_filter[] = $project['Username'];
}
else {
foreach($names_filter as $key=>$value)
{
if($value == $project['Username'])
{ break; }
else
{
$names_filter[] = $project['Username'];
}
}
}
}
If you're using PHP >= 5.5 you can take advantage of the array_column() function:
$uniqueNames = array_unique(
array_column($myArray, 'Username')
);
Prior to PHP 5.5, you can use:
$uniqueNames = array_unique(
array_map(
function($value) {
return $value['Username'];
},
$myArray
)
);
You can use the in_array function to simplify your code. Example:
$names_filter = array();
foreach($latest_projects as $project)
{
if(!in_array($project['Username'], $names_filter))
{
$names_filter[] = $project['Username'];
}
}
The in_array() function checks for the existence of a value in an array. So the foreach loop will only add a project username to the $names_filter array if it's not in the array. The output should be a list of unique usernames in the $names_filter array.
We can loop through $latest_projects and store each user name to new array ($filter). Since array can't have two elements with same keys, if the key exists it will be overwritten.
$filter = array();
foreach ($latest_projects as $project)
{
$filter[$project['Username']] = 1;
}
$filter = array_keys($filter);
I can't speak to the performance of this over other solutions, but a similar effect can be achieved with the use of array_map and array_unique. It's not as readable either though, which is just as important.
$uniqueUsers = array_unique(array_map(function ($p) { return $p['Username']; }, $latest_projects));

search associative array by value

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!!

most common values in a multidemensional array

My question is maybe repetitive but I really find it hard. (I have read related topics)
This is the array :
Array
(
[0] => Array
(
[legend] => 38440
)
[1] => Array
(
[bestw] => 9765
)
[2] => Array
(
[fiuna] => 38779
)
[3] => Array
(
[adam] => 39011
)
[4] => Array
(
[adam] => 39011
)
[5] => Array
(
[adam] => 39011
)
)
I have tried many ways to handle this array and find out the most common value. The result I expect is "adam"
$countwin = array_count_values($winnernames);
$maxwin = max($countwin);
$mostwinner = array_keys($countswin, $maxwin);
EDIT : My array is like this array("A"=>"1" , "B"=>"2" , "A"=>"1") it should return A is the most common
How about iterating your array and counting the values you've got?
$occurences = array();
foreach ($data as $row) {
foreach ($row as $key => $score) {
if (empty($occurences[$key])) {
$occurences[$key] = 1;
} else {
$occurences[$key]++;
}
}
}
and then sorting that
arsort($occurences);
and grabbing the first element of the sorted array
$t = array_keys($occurences);
$winner = array_shift($occurences);
You may try this code. A brute force method indeed. But a quick search made me to find this an useful one:
function findDuplicates($data,$dupval) {
$nb= 0;
foreach($data as $key => $val)
if ($val==$dupval) $nb++;
return $nb;
}
EDIT : Sorry, I misinterpreted your question! But it might be the first hint of finding the one with maximum counter.

PHP: pull array object element based on a criteria of the object element?

I have this array of objects. However I want to only pull out the object which meets a certain criteria. If you look at the "post_title" key, I want to only pull out the object if it does not contain a comma. Is this possible?
So in my example below, I want to pull out the array in index 2 as that is the only one that has no comma in the "post_title" key.
Array
(
[0] => stdClass Object
(
[ID] => 504
[post_title] => Playroom (Black, Custom 2)
)
[1] => stdClass Object
(
[ID] => 503
[post_title] => Playroom (Black, Custom 1)
)
[2] => stdClass Object
(
[ID] => 252
[post_title] => Play (Black)
)
)
1
Thank you for looking at this.
Yes you can but you will have to code it yourself, like this:
$results = array();
foreach ($source as $obj) {
if (strpos($obj->post_title, ',') === false) {
$results[] = $obj;
}
}
// $results will now have the elements filtered
check array_filter function - http://php.net/manual/en/function.array-filter.php
$myArray = /*snip*/;
function titleDoesNotContainComma($object) {
return strpos($object->post_title, ',') === false;
}
$filteredArray = array_filter($myArray, 'titleDoesNotContainComma');
What have you tried? You could just foreach over the array and build a new array with the relevant results. Alternatively you could use array_filter, something like this:
function hasComma( $object ) {
if( strpos( $object->post_title, ',' ) ) {
return false;
} else {
return true;
}
}
var_dump( array_filter( $array, 'hasComma' ) );

Loop an array of array

in PHP, how can i loop an array of array without know if is or not an array?
Better with an example:
Array
(
[0] => Array
(
[0] => big
[1] => small
)
[1] => Array
(
[0] => big
[1] => tiny
)
[2] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
[5] => f
)
[3] => row
[4] => cols
[5] => blablabla
[6] => Array
(
[0] => asd
[1] => qwe
)
}
any idea? thanks.
Which approach to choose depends on what you want to do with the data.
array_walk_recursive [docs] lets you traverse an array of arrays recursively.
You can use is_array to check if that element is an array, if it is, loop over it recursively.
You can use is_array to check if something is an array, and/or you can use is_object to check if it can be used within foreach:
foreach ($arr as $val)
{
if (is_array($val) || is_object($val))
{
foreach ($val as $subval)
{
echo $subval;
}
}
else
{
echo $val;
}
}
Another alternative is to use a RecursiveIteratorIterator:
$it = new RecursiveIteratorIterator(
new RecursiveArrayIterator($arr),
RecursiveIteratorIterator::SELF_FIRST);
foreach($it as $value)
{
# ... (each value)
}
The recursive iterator works for multiple levels in depth.
foreach( $array as $value ) {
if( is_array( $value ) ) {
foreach( $value as $innerValue ) {
// do something
}
}
}
That would work if you know it will be a maximum of 2 levels of nested array. If you don't know how many levels of nesting then you will need to use recursion. Or you can use a function such as array_walk_recursive
$big_array = array(...);
function loopy($array)
{
foreach($array as $element)
{
if(is_array($element))
{
// Keep looping -- IS AN ARRAY--
loopy($element);
}
else
{
// Do something for this element --NOT AN ARRAY--
}
}
}
loopy();

Categories