Multiply a multidimensional array while preserving the values
I have an array:
$cards = [
[
"from" => "Barcelona",
"to" => "Gerona Airport",
],
[
"from" => "Stockholm",
"to" => "New York JFK",
],
[
"from" => "Gerona Airport",
"to" => "Stockholm",
],
[
"from" => "Madrid",
"to" => "Barcelona",
]
];
I need to sort it to continue the trip, where it frommatches the previous one to, or it will be set as a start, if not, for example:
Array (
[0] => Array ( [from] => Madrid [to] => Barcelona )
[1] => Array ( [from] => Barcelona [to] => Gerona Airport )
[2] => Array ( [from] => Gerona Airport [to] => Stockholm )
[3] => Array ( [from] => Stockholm [to] => New York JFK )
)
I am trying to use usort:
usort($cards, function ($a, $b) {
return ( $a["to"] === $b["from"] ) ? -1 : 1;
});
print_r($cards);
But it is not sorted in the manner described. Any ideas?
We hope that the best solution will come, but if you sort as many times as there are elements in the array and return equal or greater, then this works; even if you don’t know the beginning or if the beginning is not the first element. Due to the path being usortmoved and compared, returning equally or less does not work:
foreach($cards as $card) {
usort($cards, function ($a, $b) {
return ( $a["to"] === $b["from"] ) ? 0 : 1;
});
}
, .
.
doSort($cards, $result);.
"", doSort($cards, $result, "Gerona Airport");
$cards = [
[
"from" => "Barcelona",
"to" => "Gerona Airport",
],
[
"from" => "Stockholm",
"to" => "New York JFK",
],
[
"from" => "Gerona Airport",
"to" => "Stockholm",
],
[
"from" => "Madrid",
"to" => "Barcelona",
]
];
$result = [];
function doSort($cards, &$result, $start = "Madrid") {
foreach ($cards as $key => $card) {
if ($card["from"] === $start) {
$result[] = $card;
doSort($cards, $result, $card["to"]);
}
}
}
doSort($cards, $result);
print_r($result);
:
Array
(
[0] => Array
(
[from] => Madrid
[to] => Barcelona
)
[1] => Array
(
[from] => Barcelona
[to] => Gerona Airport
)
[2] => Array
(
[from] => Gerona Airport
[to] => Stockholm
)
[3] => Array
(
[from] => Stockholm
[to] => New York JFK
)
)
here is the way. Finding a start and finding a path by iteration:
// 1. Find the start
$start = null;
$starts = array_column($cards,'from');
$ends = array_column($cards,'to');
foreach ($cards as $card) {
if (!in_array($card['from'], $ends)) $start=$card;
}
// 2. Find way
$way=[$start];
while (count($cards)>1) {
$found = false ;
foreach ($cards as $k => $card) {
if ($card['from'] == $start['to']) {
$way[] = $card;
$start = $card;
unset($cards[$k]);
$found = true ;
break 1;
}
}
if (!$found) { echo "Impossible to use all cards.\n" ; break ; }
}
print_r($way);
Outputs:
Array (
[0] => Array ([from] => Madrid [to] => Barcelona )
[1] => Array ([from] => Barcelona [to] => Gerona Airport )
[2] => Array ([from] => Gerona Airport [to] => Stockholm )
[3] => Array ([from] => Stockholm [to] => New York JFK )
)