3

I want to make an array of players sorted in order of salary from the following XML. Notice that I already sort the basketball teams by salary.

<?php
$string = <<<EOS
<Sports_Team>
<Basketball>
<Players>Tom, Jack, Sue</Players>
<salary>4</salary>
</Basketball>
<Basketball>
<Players>Josh, Lee, Carter, Bennett</Players>
<salary>6</salary>
</Basketball>
<Basketball>
<Players>Mary, Jimmy, Nancy</Players>
<salary>44</salary>
</Basketball>
</Sports_Team>
EOS;

$xml = simplexml_load_string($string);

$trees = $xml->xpath('/Sports_Team/Basketball');

function sort_trees($t1, $t2) {
    return strcmp($t1['salary'], $t2['salary']);
}

usort($trees, 'sort_trees');
var_dump($trees);
?>

I want to make an array of Players from $trees. How do I create an array object such that:

[0]-> Mary, Jimmy, Nancy
[1]-> Josh, Lee, Carter, Bennett
[2]-> Tom, Jack, Sue

Also, once I've stored my array how do I print it out visually?

1
  • 1
    I fixed one problem in my first example; $users was used instead of $trees. I also answered a part about sorting by number of players :) Commented Jul 11, 2015 at 23:03

2 Answers 2

2

Basically you have done everything perfectly right, except a couple of tiny bits which i will address bellow :)

  • In your user-defined comparison function 'sort_trees', best to compare integer directly and not the string, so no need to compare string using (strcmp).
  • Also you could use uasort() method instead of usort() to maintain index association

so your code with a tiny change can be something like the following, and finally I'm using print_r() method to print the array as you asked

<?php

function sort_trees_by_salary($t1, $t2)
{
    return (int)$t1['salary'] > (int)$t2['salary'];
}


function sort_trees_by_number_of_players($t1, $t2)
{
    return substr_count($t1->Players, ',') > substr_count($t2->Players, ',');
}


$string = <<<EOS
<Sports_Team>
<Basketball>
<Players>Tom, Jack, Sue</Players>
<salary>4</salary>
</Basketball>
<Basketball>
<Players>Josh, Lee, Carter, Bennett</Players>
<salary>6</salary>
</Basketball>
<Basketball>
<Players>Mary, Jimmy, Nancy</Players>
<salary>44</salary>
</Basketball>
</Sports_Team>
EOS;

$xml = simplexml_load_string($string);

$trees = $xml->xpath('/Sports_Team/Basketball');

// Lets say you want to sort by salary
uasort($trees, 'sort_trees_by_salary');
$results = [];
foreach ($trees as $tree) {
    $results[] = (string)$tree->Players;
}

echo 'Sorted by Salary:';
print_r($results);


// Lets say you want to sort by number of players
uasort($trees, 'sort_trees_by_number_of_players');
$results = [];
foreach ($trees as $tree) {
    $results[] = (string)$tree->Players;
}

echo 'Sorted by number of players:';
print_r($results);

Output:

Sorted by Salary:Array
(
    [0] => Mary, Jimmy, Nancy
    [1] => Josh, Lee, Carter, Bennett
    [2] => Tom, Jack, Sue
)
Sorted by number of players:Array
(
    [0] => Mary, Jimmy, Nancy
    [1] => Tom, Jack, Sue
    [2] => Josh, Lee, Carter, Bennett
)

Please note: considering the user-defined comparison function works with the reference the above example will apply both sorting methods on your set of data, first to order the list based on the salary and second based on the number players

Sign up to request clarification or add additional context in comments.

2 Comments

How would I create a sorted array by the number of players?
@cooldood3490, I have included a solution to sort your list based on the number of players according to the number of commas (,) found in each row. however the best approach is to include the number of players in your xml dataset. but that only is possible if you have access to the data source/provider as well.
0

Assuming you have PHP 5.3+, try this:

$playersArray = array_map(
    create_function('$inputArray', 'return (string) $inputArray->Players;'),
    $trees
);

For example:

php > var_dump($playersArray);
array(3) {
  [0]=>
  string(18) "Mary, Jimmy, Nancy"
  [1]=>
  string(26) "Josh, Lee, Carter, Bennett"
  [2]=>
  string(14) "Tom, Jack, Sue"
}

If you're using older PHP, you need to use a real (non-anonymous) function for array_map(), or use create_function():

$playersArray = array_map(
    create_function('$inputArray', 'return (array) $inputArray->Players;'),
    $users
);

To answer the last part, how do you print it out visually, well, that depends! If you just want to dump it to view it for debugging purposes, use var_dump() or print_r(). Both take the array variable as the only needed argument. var_dump() is a bit more verbose.

This is var_dump() (manual):

php > var_dump($playersArray);
array(3) {
  [0]=>
  string(18) "Mary, Jimmy, Nancy"
  [1]=>
  string(26) "Josh, Lee, Carter, Bennett"
  [2]=>
  string(14) "Tom, Jack, Sue"
}

This is print_r() (manual):

php > print_r($playersArray);
Array
(
    [0] => Mary, Jimmy, Nancy
    [1] => Josh, Lee, Carter, Bennett
    [2] => Tom, Jack, Sue
)

Otherwise, to process and display output for end users based on the array, you'll likely want to loop through it and process it, or use array_map() similarly to above to generate the output. Also, if you want to experiment with this in a PHP Console similarly to what I did in my examples, you can run php -a and type your code at the prompt.

Edit

To answer the question from the comments, try this:

/* Sort by the number of ',' characters in the string. */
function sort_players($a, $b) {
    $ca = substr_count($a, ',');
    $cb = substr_count($b, ',');
    if ($ca == $cb) return 0;
    return ($ca > $cb) ? -1 : 1;
}

usort($playersArray, 'sort_players');

2 Comments

Please do not use create_function without static caching. That creates global functions for each calls, those are never disposed.
Simple Wrapper: function create_func($arg, $code) { static $c; if (!isset($c[$arg][$code])) $c[$arg][$code] = create_function($arg, $code); return $c[$arg][$code]; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.