I'm slowly learning PHP, and I need some help with sorting through a foreach() loop. Currently, this loop grabs an ID and Name from a database table and displays it in a list, however, I'm having problems sorting that list in alphabetical order. This is what is looks like now where all the records are retrieved and presented in a neat list:
<?php foreach ($disabilities as $disability):?>
<option value=<?=($disability->id)?>><?=($disability->name)?></option>
<?php endforeach; ?>
And this is what I have tried:
<?php myArray = array($disabilities)
sort($disabilities)
foreach ($disabilities as $disability): ?>
<option value=<?=($disability->id)?>><?=($disability->name)?></option>
<?php endforeach; ?>
Any tips on whether I'm on the right/wrong path would be greatly appreciated!
you can achieve this by two ways.
1) sort this while querying from the database.
2) sort arrays in php, here is an example code for sorting in php.
//stdclass object arrays to simple array
$disabilities = json_decode(json_encode($object), True);
$sortArray = array();
foreach($disabilities as $disability){
foreach($disability as $key=>$value){
if(!isset($sortArray[$key])){
$sortArray[$key] = array();
}
$sortArray[$key][] = $value;
}
}
$orderby = "name"; //change this to whatever key you want to apply sorting for
array_multisort($sortArray[$orderby], SORT_ASC, $disabilities);
hope it works for you
Edit: As I have changed it from stdClass Object to array now you will echo like this
echo $disability['name'];
You can use PHP usort function add user defined comparison function.
$obj = (object) array(
['id' => '1', 'name' => 'Ronda'],
['id' => '2', 'name' => 'Aba'],
['id' => '3', 'name' => 'Mac']
);
//convert obj to array usort only accept array
$disabilities = json_decode(json_encode($obj), true);
//define custom function
function sortByName($a, $b) {
//compare two strings
return strcmp($a['name'], $b['name']);
}
//sort using usort before use
usort($disabilities, 'sortByName');
//output
Array ( [0] => Array ( [id] => 2 [name] => Aba ) [1] => Array ( [id] => 3 [name] => Mac ) [2] => Array ( [id] => 1 [name] => Ronda ) )
Working demo: https://repl.it/repls/GruesomeExaltedDevicedriver, After sort the array you can directly use in your foreach.
Related
This question already has answers here:
Find highest value in multidimensional array [duplicate]
(9 answers)
Closed 5 years ago.
i need to get the the max or highest value in a multi dimensional array.
here is my array $array:
[pay] => Array
(
[0] => Array
(
[title] => Array
(
[name] => 'hi'
)
[payment] => Array
(
[amount] => 35
[currency] => USD
)
)
[1] => Array
(
[title] => Array
(
[name] => 'lol'
)
[payment] => Array
(
[amount] => 50
[currency] => USD
)
)
[2] => Array
(
[title] => Array
(
[name] => 'ok'
)
[payment] => Array
(
[amount] => 30
[currency] => USD
)
)
)
i need to get the max value for amount which is 50. how can i do that?
here is what i tried but it did not work:
$max = -9999999; //will hold max val
$found_item = null; //will hold item with max val;
foreach($array as $k=>$v)
{
if($v['Total']>$max)
{
$max = $v['Total'];
$found_item = $v;
}
}
Simple as this one-liner. Get the payment column data, then pull the amount data from that generated array, then get the max value. Done and done. (Sorry it took me so long -- I had to convert your posted array to a usable php array.)
Input:
$array=["pay" => [
["title"=>["name"=>'hi'],"payment"=>["amount"=>35,"currency"=>"USD"]],
["title"=>["name"=>'lol'],"payment"=>["amount"=>50,"currency"=>"USD"]],
["title"=>["name"=>'ok'],"payment"=>["amount"=>30,"currency"=>"USD"]]
]
];
Method #1 (Demo):
echo max(array_column(array_column($array["pay"],"payment"),"amount"));
Method #2 (Demo):
$max=0;
foreach($array["pay"] as $subarray){
if($max<$subarray["payment"]["amount"]){
$max=$subarray["payment"]["amount"];
}
}
echo $max;
Method #3 (Demo):
$payments=array_column($array["pay"],"payment"); // declare payments array
rsort($payments); // sort by amount DESC
echo $payments[0]["amount"]; // access the first amount value
Output:
50
The benefits to method #1 are: code brevity, no condition statements, no global variable declarations/overwriting, just straight to the max value. What's not to love!
If method #1 is too scary, you can go with my method #2 (which was first posted by aendeerei). I don't prefer it because it requires the extra steps of initializing the $max variable, performing a conditional check on each iteration, and overwriting the $max variable when appropriate. Actual performance on the foreach loop is going to depend on the size of your array, but the difference between the two methods is going to be unnoticable to humans.
Method 3 might be my new favorite because there are no conditionals and just two functions before it is accessed purely by keys. However, it does require the declaration of a partial copy of the input array which must be sorted. Anyhow, take your pick -- it's all the same outcome.
Use Usort and get the 1st index
$arr= array
(
array
(
'payment' => array
(
'amount' => 35,
'currency' => 'USD'
)
),
array
(
'payment' => array
(
'amount' => 50,
'currency' => 'USD'
)
),
array
(
'payment' => array
(
'amount' => 80,
'currency' => 'USD'
)
)
);
function sortAmount($x, $y) {
return $y['payment']['amount'] - $x['payment']['amount'];
}
usort($arr, 'sortAmount');
echo "<pre>";
$highest=$arr[0];
print_r($highest)
//for value only
$highest=$arr[0]['payment']['amount'];
Working fiddle
http://phpfiddle.org/main/code/p5hw-ivei
$max = 0;
foreach ($array['pay'] as $key => $item) {
$amount = $item['payment']['amount'];
if ($amount > $max) {
$max = $amount;
}
}
echo $max;
Shorthand:
$result = array_reduce($array['pay'], function($a, $b){
return $a ? ($a['payment']['amount'] > $b['payment']['amount'] ? $a : $b) : $b;
});
var_dump($result['payment']['amount']);
Try this hope this will be helpful. Here we are just using simple foreach to get it done.
Solution 1:
try this code snippet here
$max=0;
foreach($yourArray["pay"] as $value)
{
if($max<$value["payment"]["amount"])
{
$max=$value["payment"]["amount"];
}
}
echo $max;
Solution 2:
Just for testing purpose i have converted you array to json. Here we are using array_column two times to get the columns
Try this code snippet here
$internals=array_column($yourArray["pay"],"payment");//retrieving payments
$amounts=array_column($internals, "amount");//retrieving amounts
arsort($amounts);
print_r(array_values($amounts)[0]);
Consider this example with an array named pay. You can adapt this method for your own array. This code will work for an array of n elements. Here I consider 3 as the number of elements in the array named $pay. You can replace the max elements in the array in the place of 3 for controlling the loop control variable 'i'.
$big=$pay[0];
for($i=1; $i<3; $i++){
if($pay[i]>$big)
$big=$pay[i];
}
echo $big;
I hope this is what you are looking for. Ask for any clarification.
As a newbie, does anyone have any good tutorials to help me understand different levels of an array? What I'm trying to learn is how to echo different levels, e.g. here is the output array:
Array
(
[meta] =>
Array
(
[total_record_count] => 1
[total_pages] => 1
[current_page] => 1
[per_page] => 1
)
[companies] =>
Array
(
[0] =>
Array
(
[id] => 291869
[url] => https://api.mattermark.com/companies/291869
[company_name] => gohenry.co.uk
[domain] => gohenry.co.uk
)
)
[total_companies] => 1
[page] => 1
[per_page] => 1
)
And here is the code to parse the array:
foreach($jsonObj as $item)
{
echo $item['total_companies'];
}
I'm really struggling to find the structure and how to output each items, e.g. tried things like:
echo $item[0]['total_companies'];
echo $item['companies'][0]['id'];
Any help or pointers would be greatly received.
Well, Lets start, You have a multi-dimensional array. For a multi-dimensional array you need to use looping e.g: for, while, foreach. For your purpose it is foreach.
Start with the array dimension, Array can be multi-dimension, Like you have multi-dimension. If you have an array like below, then it is single dimension.
array(
key => value,
key2 => value2,
key3 => value3,
...
)
Now, How can you know what is a multi-dimension array, If you array has another array as child then it is called multi-dimensional array, like below.
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);
Its time to work with your array. Suppose you want to access the value of company_name, what should you do?? Let your array name is $arr.
First you need to use a foreach loop like:
foreach($arr as $key => $val)
The keys are (meta, companies, total_companies...), they are in the first dimension. Now check if the key is company_name or not, if it matches than you got it. Or else you need to make another loop if the $val is an array, You can check it using is_array.
By the same processing at the last element your loop executes and find your value.
Learning
Always a good idea to start with the docs:
arrays: http://php.net/manual/en/language.types.array.php
foreach: http://php.net/manual/en/control-structures.foreach.php
As for tutorials, try the interactive tutorial over at codecademy: https://www.codecademy.com/learn/php
Unit 4 has a tutorial on arrays
Unit 11 has a lesson on advanced arrays.
Your code
As for your code, look at the following which I will show you your array structure and how to access each element. Perhaps that will make things clearer for you.
So lets say your array is named $myArray, see how to access each part via the comments. Keep in mind this is not php code, I'm just showing you how to access the array's different elements.
$myArray = Array
(
// $myArray['meta']
[meta] => Array (
// $myArray['meta']['total_record_count']
[total_record_count] => 1
// $myArray['meta']['total_pages']
[total_pages] => 1
// $myArray['meta']['current_page']
[current_page] => 1
// $myArray['meta']['per_page']
[per_page] => 1
)
// $myArray['companies']
[companies] => Array (
// $myArray['companies'][0]
[0] => Array (
// $myArray['companies'][0]['id']
[id] => 291869
// $myArray['companies'][0]['url']
[url] => https://api.mattermark.com/companies/291869
// $myArray['companies'][0]['company_name']
[company_name] => gohenry.co.uk
// $myArray['companies'][0]['domain']
[domain] => gohenry.co.uk
)
)
// $myArray['total_companies']
[total_companies] => 1
// $myArray['page']
[page] => 1
// $myArray['per_page']
[per_page] => 1
)
As for your for each loop
foreach($jsonObj as $item)
{
echo $item['total_companies'];
}
What the foreach loop is doing is looping through each first level of the array $jsonObj, so that would include:
meta
companies
total_companies
page
per_page
Then within the curly braces {} of the foreach loop you can refer to each level by the variable $item.
So depending on what you want to achieve you need to perhaps change your code, what is it you're trying to do as it's not really clear to me.
As for the code within the loop:
echo $item['total_companies'];
It won't work because you're trying to access an array with the index of total_companies within the first level of the $jsonObj array which doesn't exist. For it to work your array would have to look like this:
$jsonObj = array (
'0' => array ( // this is what is reference to as $item
'total_companies' => 'some value'
)
)
What you want to do is this:
foreach($jsonObj as $item)
{
echo $jsonObj['total_companies'];
}
As for your final snippet of code:
echo $item[0]['total_companies'];
Answered this above. Access it like $jsonObj['total_companies'];
echo $item['companies'][0]['id'];
If you want to loop through the companies try this:
foreach($jsonObj['companies'] as $item)
{
// now item will represent each iterable element in $jsonObj['companies]
// so we could do this:
echo $item['id'];
}
I hope that all helps! If you don't understand please make a comment and I'll update my answer.
Please take a look in to here and here
Information about php arrays
Try recursive array printing using this function:
function recursive($array){
foreach($array as $key => $value){
//If $value is an array.
if(is_array($value)){
//We need to loop through it.
recursive($value);
} else{
//It is not an array, so print it out.
echo $value, '<br>';
}
}
}
if you know how deep your array structure you can perform nested foreach loop and before every loop you have to check is_array($array_variable), like :
foreach($parent as $son)
{
if(is_array($son))
{
foreach($son as $grandson)
{
if(is_array($son))
{
foreach($grandson as $grandgrandson)
{
.....
......
.......
}
else
echo $grandson;
}
else
echo $parent;
}
else
echo $son;
}
hope it will help you to understand
Most likely I'm doing this wayyyyyy too complicated. But I'm in the need of converting multiple arrays to multidimensional array key's. So arrays like this:
Array //$original
(
[0] => 500034
[1] => 500035 //these values need to become
//consecutive keys, in order of array
)
Needs to become:
Array
(
[50034][50035] => array()
)
This needs to be done recursively, as it might also require that it becomes deeper:
Array
(
[50034][50036][50126] => array() //notice that the numbers
//aren't necessarily consecutive, though they are
//in the order of the original array
)
My current code:
$new_array = array();
foreach($original as $k => $v){ //$original from first code
if((gettype($v) === 'string' || gettype($v) === 'integer')
&& !array_key_exists($v, $original)){ //check so as to not have illigal offset types
$new_array =& $original[array_search($v, $original)];
echo 'In loop: <br />';
var_dump($new_array);
echo '<br />';
}
}
echo "After loop <br />";
var_dump($new_array);
echo "</pre><br />";
Gives me:
In loop:
int(500032)
In loop:
int(500033)
After loop
int(500033)
Using this code $new_array =& $original[array_search($v, $original)]; I expected After loop: $new_array[50034][50035] => array().
What am I doing wrong? Been at this for hours on end now :(
EDIT to answer "why" I'm trying to do this
I'm reconstructing facebook data out of a database. Below is my own personal data that isn't reconstructing properly, which is why I need the above question answered.
[500226] => Array
(
[own_id] =>
[entity] => Work
[name] => Office Products Depot
[500227] => Array
(
[own_id] => 500226
[entity] => Employer
[id] => 635872699779885
)
[id] => 646422765379085
)
[500227] => Array
(
[500228] => Array
(
[own_id] => 500227
[entity] => Position
[id] => 140103209354647
)
[name] => Junior Programmer
)
As you can see, the ID [500227] is a child of [500226], however, because I haven't got the path to the child array, a new array is created. The current parentage only works to the first level.
[own_id] is a key where the value indicates which other key should be its parent. Which is why the first array ([500226]) doesn't have a value for [own_id].
If you want to do something recursively, do it recursively. I hope that's what you meant to do.
public function pivotArray($array, $newArray)
{
$shifted = array_shift($array);
if( $shifted !== null )
{
return $this->pivotArray($array, array($shifted=>$newArray));
}
return $newArray;
}
$array = array(432, 432532, 564364);
$newArray = $this->pivotArray($array, array());
Edit: After the question's edit it doesn't seem to be very relevant. Well, maybe someone will find it useful anyway.
Array
(
[data] => Array
(
[0] => Array
(
[name] => Nicki Escudero
[id] => 27700035
)
[1] => Array
(
[name] => Yorgo Nestoridis
[id] => 504571368
)
)
)
How can I sort this multidimensional array using its name?
I tried with array_multisort but it's not working.
If you want to use array_multisort, you would use the following:
$array = array(
'data' => array(
array(
'name' => 'Yorgo Nestoridis',
'id' => 504571368,
),
array(
'name' => 'Nicki Escudero',
'id' => 27700035,
),
),
);
$names = array();
foreach($array['data'] as $datum) {
$names[] = $datum['name'];
}
array_multisort($names, SORT_ASC, $array['data']);
var_dump($array); // now sorted by name
The other choice is to use a custom comparison function:
function compareNames($a, $b) {
return strcmp($a['name'], $b['name']);
}
usort($array['data'], 'compareNames');
It is already sorted :-) What do you want to sort by? And where is the data coming from? if you get it from a DB you should sort differently.
If those are the only two values you have, you can try making id the index of the array and the name can be the value. You can then use asort to sort the array by name and maintain the index-value relation.
By making id the index, I mean $array[27700035] would return Nicki Escudero.
// Copy the array to a new array.
foreach($array as $val) {
$newArray[$val['id']] = $val['name'];
}
asort($newArray);
Edit: I've gone through the manual and you can also use usort with a custom comparison function. Although I've never used this and can be of very little help... PHP usort
Total PHP Noob and I couldn't find an answer to this specific problem. Hope someone can help!
$myvar is an array that looks like this:
Array (
[aid] => Array (
[0] => 2
[1] => 1
)
[oid] => Array(
[0] => 2
[1] => 1
)
)
And I need to set a new variable (called $attributes) to something that looks like this:
$attributes = array(
$myvar['aid'][0] => $myvar['oid'][0],
$myvar['aid'][1] => $myvar['oid'][1],
etc...
);
And, of course, $myvar may contain many more items...
How do I iterate through $myvar and build the $attributes variable?
use array_combine()
This will give expected result.
http://php.net/manual/en/function.array-combine.php
Usage:
$attributes = array_combine($myArray['aid'], $myArray['oid']);
Will yield the results as requested.
Somthing like this if I understood the question correct
$attributes = array();
foreach ($myvar['aid'] as $k => $v) {
$attributes[$v] = $myvar['oid'][$k];
}
Your requirements are not clear. what you mean by "And, of course, $myvar may contain many more items..." there is two possibilties
1st. more then two array in main array. like 'aid', 'oid' and 'xid', 'yid'
2nd. or two main array with many items in sub arrays like "[0] => 2 [1] => 1 [2] => 3"
I think your are talking about 2nd option if so then use following code
$aAid = $myvar['aid'];
$aOid = $myvar['oid'];
foreach ($aAid as $key => $value) {
$attributes['aid'][$key] = $value;
$attributes['oid'][$key] = $myvar['oid'][$key];
}
You can itterate though an array with foreach and get the key and values you want like so
$attributes = array()
foreach($myvar as $key => $val) {
$attributes[$key][0] = $val;
}