PHP my_asort() and my_ksort() - php

I'm working on this problem of sorting in php.
I have to write my own sorting functions, using my_asort() and my_ksort() functions that do exactly the same as asort and ksort respectively.
However I'm not able to get the correct output (I'm new to php), hence any help on how to correct this, would be greatly appreciated.
This is the code I typed up:
<?php
echo "Original Array<br><br>";
$member = array("Jack" => "55kg", "Bill" => "35kg", "Aaron" => "60kg", "Daniel" => "80kg" );
foreach ($member as $user => $weight) {
echo "$user = $weight <br>";
}
echo "<br><br>";
function my_asort($member)
{
$keys=array_keys($member);
sort($keys);
foreach($keys as $key)
{
$val=$member[$key];
unset($member[$key]);
$member[$key]=$val;
}
}
echo "Sorted By user <br><br>";
foreach ($member as $user => $weight) {
echo "$user = $weight <br>";
}
echo "<br><br>";
function my_ksort($member)
{
$keys=array_keys($member);
sort($keys);
foreach($keys as $key)
{
$val=$member[$key];
unset($member[$key]);
$member[$key]=$val;
}
}
echo "Sorted By weight <br><br>";
foreach ($member as $user => $weight) {
echo "$user = $weight <br>";
}
?>
This is what it displays: (It doesn't do any sorting, what am I doing wrong?)
Original Array
Jack = 55kg
Bill = 35kg
Aaron = 60kg
Daniel = 80kg
Sorted By user
Jack = 55kg
Bill = 35kg
Aaron = 60kg
Daniel = 80kg
Sorted By weight
Jack = 55kg
Bill = 35kg
Aaron = 60kg
Daniel = 80kg

You need to call your functions (or use the code without a function declaration). You just defined them inside your code.
So if you want to use them, you need to call them and your code will look like:
<?php
function my_ksort(&$member)
{
$keys=array_keys($member);
sort($keys);
foreach($keys as $key)
{
$val=$member[$key];
unset($member[$key]);
$member[$key]=$val;
}
}
function my_asort(&$member)
{
$keys=array_keys($member);
sort($keys);
foreach($keys as $key)
{
$val=$member[$key];
unset($member[$key]);
$member[$key]=$val;
}
}
echo "Original Array<br><br>";
$member = array("Jack" => "55kg", "Bill" => "35kg", "Aaron" => "60kg", "Daniel" => "80kg" );
foreach ($member as $user => $weight) {
echo "$user = $weight <br>";
}
echo "<br><br>";
my_asort($member);
echo "Sorted By user <br><br>";
foreach ($member as $user => $weight) {
echo "$user = $weight <br>";
}
echo "<br><br>";
my_ksort($member);
echo "Sorted By weight <br><br>";
foreach ($member as $user => $weight) {
echo "$user = $weight <br>";
}

Two problems :
You are not using the functions you created :
my_asort($member);
my_ksort($member);
And you'll have to add a reference (&) on your array in the parameters since you are not returning anything but modifying arrays :
function my_asort(&$member)
function my_ksort(&$member)
(I didn't check if the results correspond to the actual asort and ksort functions, but since it looks like a school homework, I'm sure you will find out now that you have an output of your functions)

You have not called methods anywhere in your code. You just provided the method definition but not calling.

Build your array like this:
$member[] = array('name' => 'Jake', 'weight' => '54');
$member[] = array('name' => 'Bill', 'weight' => '35');
$member[] = array('name' => 'Daniel', 'weight' => '80');
Then use the function bellow:
$new_arr = array_sort($member, 'name', 'SORT_ASC');
$new_arr2 = array_sort($member, 'weight', 'SORT_DESC');
print_r($new_arr);
print_r($new_arr2);
function array_sort($array, $on, $order='SORT_ASC'){
$new_array = array();
$sortable_array = array();
if (count($array) > 0) {
foreach ($array as $k => $v) {
if (is_array($v)) {
foreach ($v as $k2 => $v2) {
if ($k2 == $on) {
$sortable_array[$k] = $v2;
}
}
} else {
$sortable_array[$k] = $v;
}
}
switch ($order) {
case 'SORT_ASC':
asort($sortable_array);
break;
case 'SORT_DESC':
arsort($sortable_array);
break;
}
foreach ($sortable_array as $k => $v) {
$new_array[$k] = $array[$k];
}
}
return $new_array;
}

Related

PHP read value form multidimensional array

its easy for sure..
i have code like this:
$indeks = 0;
foreach ($list as $k => $v)
{
$data['fname'] = $customer->firstname;
$data['lname'] = $customer->lastname;
$data['code'] = $code['code'];
$tablica[$indeks] = $data;
$indeks++;
and i want to read only 'code' value for each array.
i try:
foreach($tablica as $k => $v){
foreach ($v as $key => $value ) {
echo $value
}
}
but i get all arrays values.
when i try
foreach($tablica as $k => $v){
foreach ($v['code'] as $key => $value ) {
echo $value
}
}
i have nothing...
thx for help
You can use array_column function to get all values of column, for example:
foreach (array_column($tablica, 'code') as $value) {
echo $value;
}
I think a For loop should help
for($i=0;$i<count($tablica);$i++){
echo $tablica[$i]['code'];
}
or get all Codes into an Array
$code = array();
for($i=0;$i<count($tablica);$i++){
$code[$i] = $tablica[$i]['code'];
}
You don't need nested loops.
foreach ($tablica as $value) {
echo $value['code'];
}
DEMO

Separate multidimensional array into separate arrays

I am trying to get my head around arrays.
The arrays should look like this:
$questions[$a] => array( [0] => No, comment1
[1] => Yes, comment2
[2] => No, comment3 )
$answer[$a] => array( [0] => No
[1] => Yes
[3] => No )
$comment[$a] => array( [0] => comment1
[1] => comment2
[3] => comment3 )
=========================================================================
SECOND EDIT: Need to execute this in the loop to create a third array -
if($answer[$a] == "Yes") { $display[$a] = "style='display:none'";
} else { $display[$a] = "style='display:block'"; }
This is what i have: (28th for minitech)
while ($a > $count)
{
if($count > 11) {
foreach($questions as $q) {
list($answer, $comments[]) = explode(',', $q);
if($answer === "Yes") {
$display[$a] = "style='display:none'";
} else {
$display[$a] = "style='display:block'";
}
$answers[] = $answer;
}
}
$a++;
}
If they are actually strings, explode works:
$answers = array();
$comments = array();
$display = array();
foreach(array_slice($questions, 11) as $question) {
list($answer, $comments[]) = explode(',', $question);
$display[] = $answer === 'Yes' ? 'style="display: none"' : 'style="display: block"';
$answers[] = $answer;
}
Here’s a demo!
Change your while loop to this
while ...
{
$parts = explode(',', $questions[$a]);
$answer[$a][] = trim($parts[0]);
$comment[$a][] = trim($parts[1]);
}
In your original code you were overwriting the $answer[$a] and $comment[$a] each time, not appending to the end of an array
$questions[$a] = array('Q1?' => 'A1', 'Q2?' => 'A2', 'Q3?' => 'A3');
foreach($questions[$a] as $key => $value)
{
$comment[$a][] = $key;
$answer[$a][] = $value;
}
This should work.
foreach ($questions[$a] as $key=>$value){
$temp = explode(',',$value);
$answer[$key] = $temp[0];
$comment[$key] = $temp[1];
}
$key will have 0,1,2 respectively. $value will have the values for each $question[$a](No,Comment1 ....)
Can't think of a funky one-liner, but this should do it:
foreach ($questions as $a => $entries) {
foreach ($entries as $k => $entry) {
$parts = array_map('trim', explode(',', $entry));
$answer[$a][$k] = $parts[0];
$comment[$a][$k] = $parts[1];
}
}
$questions = array( 0 => 'No,comment1',1 => 'Yes,comment2',2 => 'No,comment3' );
foreach($questions as $question)
{
$parts = explode(",",$question);
$answer[] = $parts[0];
$comment[] = $parts[1];
}
echo "<pre>";
print_r($answer);
print_r($comment);
Here is the right answer
foreach($questions as $key => $question){
foreach($question as $q => $data){
$data= explode(',',$data);
$comments[$key][$q] = $data[0];
$answer[$key][$q] = $data[1];
}
}
If the values in $questions are comma-separated strings you could use an array_walk function to populate your $answer and $comment arrays
$question = array(...); //array storing values as described
$answer = array();
$comment = array();
array_walk($question, function ($value, $key) use ($answer,$comment) {
$value_array = explode(',', $value);
$answer[$key] = $value_array[0];
$comment[$key] = $value_array[1];
});
Note that this is shown using an anonymous function (closure) which requires PHP >= 5.3.0. If you had a lower version of PHP, you would need to declare a named function, and declare $answer and $comment as globals in the function. I think this is a hacky approach (using globals like this) so if I was using PHP < 5.3 I would probably just use a foreach loop like other answers to your question propose.
Functions like array_walk, array_filter and similar functions where callbacks are used are often great places to leverage the flexibility provided by anonymous functions.

Split an array into sub arrays

I would like to split an array:
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
based on the color attribute of each item, and fill corresponding sub arrays
$a = array("green", "yellow", "blue");
function isGreen($var){
return($var->color == "green");
}
$greens = array_filter($o, "isGreen");
$yellows = array_filter($o, "isYellow");
// and all possible categories in $a..
my $a has a length > 20, and could increase more, so I need a general way instead of writing functions by hand
There doesn't seem to exist a function array_split to generate all filtered arrays
or else I need a sort of lambda function maybe
You could do something like:
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$greens = array_filter($o, function($item) {
if ($item->color == 'green') {
return true;
}
return false;
});
Or if you want to create something really generic you could do something like the following:
function filterArray($array, $type, $value)
{
$result = array();
foreach($array as $item) {
if ($item->{$type} == $value) {
$result[] = $item;
}
}
return $result;
}
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$greens = filterArray($o, 'color', 'green');
$yellows = filterArray($o, 'color', 'yellow');
In my second example you could just pass the array and tell the function what to filter (e.g. color or some other future property) on based on what value.
Note that I have not done any error checking whether properties really exist
I would not go down the road of creating a ton of functions, manually or dynamically.
Here's my idea, and the design could be modified so filters are chainable:
<?php
class ItemsFilter
{
protected $items = array();
public function __construct($items) {
$this->items = $items;
}
public function byColor($color)
{
$items = array();
foreach ($this->items as $item) {
// I don't like this: I would prefer each item was an object and had getColor()
if (empty($item->color) || $item->color != $color)
continue;
$items[] = $item;
}
return $items;
}
}
$items = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$filter = new ItemsFilter($items);
$greens = $filter->byColor('green');
echo '<pre>';
print_r($greens);
echo '</pre>';
If you need more arguments you could use this function:
function splitArray($array, $params) {
$result = array();
foreach ($array as $item) {
$status = true;
foreach ($params as $key => $value) {
if ($item[$key] != $value) {
$status = false;
continue;
}
}
if ($status == true) {
$result[] = $item;
}
}
return $result;
}
$greensAndID1 = splitArray($o, array('color' => 'green', 'id' => 1));

PHP Merge Similar Objects In A Multidimensional Array

I have a multidimensional array in PHP, something that looks like:
array(array(Category => Video,
Value => 10.99),
array(Category => Video,
Value => 12.99),
array(Category => Music,
Value => 9.99)
)
and what I would like to do is combine similar categories and output everything into a table, so the output would end up being:
<tr><td>Video</td><td>23.98</td></tr>
<tr><td>Music</td><td>9.99</td></tr>
Any suggestions on how to do this?
EDIT:
I can have these in two different arrays if that would be easier.
A simple loop will do:
$array = [your array];
$result = array();
foreach ($array as $a) {
if (!isset($result[$a['Category']])) {
$result[$a['Category']] = $a['Value'];
} else {
$result[$a['Category']] += $a['Value'];
}
}
foreach ($result as $k => $v) {
echo '<tr><td>' . htmlspecialchars($k) . '</td><td>' . $v . '</td></tr>';
}
$result = array();
foreach ($array as $value) {
if (isset($result[$value['Category']])) {
$result[$value['Category']] += $value['Value'];
} else {
$result[$value['Category']] = $value['Value'];
}
}
foreach ($result as $category => $value) {
print "<tr><td>$category</td><td>$value</td></tr>";
}

PHP Looping through an array with strings AND an array inside

This is a basic looping question but with a twist, so it's likely that i'm missing something easy - apologies in advance...
I'm trying to pull the results from an array $testoutput - which is filled with 3 arrays:
Running the following code:
foreach ($testoutput as $ID => $Array) {
echo $Array . "<BR>";
}
Returns:
ARRAY
ARRAY
ARRAY
Adding a second nested loop with the following code:
foreach ($testoutput as $ID => $Array) {
foreach ($Array as $ID => $L1item) {
echo $L1item . "<BR>";
}
}
Results in:
String1a
String1b
String1c
ARRAY
String2a
String2b
String2c
ARRAY
String3a
String3b
String3c
ARRAY
I'm fine with retuning all of the above strings, however, I can't figure out how to return the values from the 3rd-level of nested Arrays.
Is there an easy way to do this?
Many thanks in advance.
You can use array_map
$testoutput = array('x', array('y', 'z', array('1', '2', '3')));
function output($element) {
if(is_array($element)) {
array_map('output', $element); //RECURSION
return;
}
echo $element;
}
array_map('output', $testoutput);
Or if you prefer, you can use array_walk_recursive:
function output(&$value, $index) {
echo $value;
}
array_walk_recursive($testoutput, 'output');
Try this:
/**
* array nested_array_map(callback $callback, array $array)
* Warning - doesn't check for recursion,
* therefore child arrays shouldn't contain references to any of parent level arrays
*
* #param $callback, function
* #param $array, array of elements to map the function to
* #return array
*/
function nested_array_map($callback, $param) {
if (!is_array($param)) {
return call_user_func($callback, $param);
}
$result = array();
foreach ($param as $index => $value) {
$result[$index] = nested_array_map($callback, $value);
}
return $result;
}
function echo_value($value) {
echo "$value\n";
return $value;
}
$test = array(
'1st level'
,array(
'2nd level'
,array(
'3rd level'
)
,'2nd level'
)
,array(
'2nd level'
)
,'1st level'
);
$result = nested_array_map('echo_value', $test);
foreach ($testoutput as $key1 => $value1) {
foreach ($value1 as $key2 => $value2) {
if(is_array($value2))
{
foreach ($value2 as $key3 => $value3) {
echo $value3;
}
}
else
{
echo $value2;
}
}
}

Categories