Jump to content

array_multisort with 2d array


HeidiR

Recommended Posts

Hello all,

 

I'm trying to use array_multisort with a 2d array (code below). I have a simple example below which produces the following incorrect results:

 

0) b -> 2

1) a -> 1

2) c -> 3

 

0) 2 -> b

1) 1 -> a

2) c -> 3

 

Note: This example is similar to example #2 on php.net but it doesn't seem to work as advertised. What am I missing???

 

Thanks,

 

HeidiR

 

 

 

<?php

 

$ar[0][0] = "b";

$ar[1][0] = "a";

$ar[2][0] = "c";

$ar[0][1] = "2";

$ar[1][1] = "1";

$ar[2][1] = "3";

 

for($i = 0; $i <= count($ar) -1; $i++) {

echo ($i . ") " . $ar[$i][0] . " -> " . $ar[$i][1] . "<br />");

}

 

echo ("<br />");

 

array_multisort($ar[0], SORT_ASC, SORT_STRING, $ar[1], SORT_ASC, SORT_STRING);

 

for($i = 0; $i <= count($ar) -1; $i++) {

echo ($i . ") " . $ar[$i][0] . " -> " . $ar[$i][1] . "<br />");

}

 

?>

Link to comment
https://forums.phpfreaks.com/topic/127237-array_multisort-with-2d-array/
Share on other sites

If they're already linked in the array, just use usort() to sort the values you want and the other one will come along for the ride...

 

This should work... (basically copied/pasted from the php manual http://us2.php.net/usort )

function cmp($a, $b)
{
    strcmp($a[0], $b[0]);
}

$ar[0][0] = "b";
$ar[1][0] = "a";
$ar[2][0] = "c";
$ar[0][1] = "2";
$ar[1][1] = "1";
$ar[2][1] = "3";

usort($ar, "cmp");
print_r($ar);

If they're already linked in the array, just use usort() to sort the values you want and the other one will come along for the ride...

 

This should work... (basically copied/pasted from the php manual http://us2.php.net/usort )

function cmp($a, $b)
{
    strcmp($a[0], $b[0]);
}

$ar[0][0] = "b";
$ar[1][0] = "a";
$ar[2][0] = "c";
$ar[0][1] = "2";
$ar[1][1] = "1";
$ar[2][1] = "3";

usort($ar, "cmp");
print_r($ar);

 

Thanks for the quick reply and solution. This works great for string arrays.

I have extended your example and created another function to handle sorting a 2d array with numeric values. The usort and _ncmp functions below sort the numeric values correctly.

 

usort($ar, '_ncmp')

 

function _ncmp($a, $b) {

if($a[0] < $b[0]) //col1

return -1;

else

return 1;

}

 

Is there a way to call _ncmp from usort with an argument to dynamically change the sort column? Something like:

 

function _ncmp($a, $b, $sort_col) {

if($sort_col] < $b[$sort_col])

return -1;

else

return 1;

}

it would be easiest to just change the cmp function to

 

<?php
function cmp($a, $b)
{
return strnatcmp($a[0], $b[0]);
}
?>

 

As for passing params to the function called by usort? It might be cleanest if you implement it in a class...

<?php
class OrderedMDArray {
private $array;
private $sortKey;

public function __construct($array, $sortKey) {
	$this->array = $array;
	$this->sortKey = $sortKey;
}

public function get() {
	usort($this->array, array($this, 'cmp'));
	return $this->array;
}

private function cmp($str1, $str2) {
	return strnatcmp($str1[$this->sortKey], $str2[$this->sortKey]);
}
}

$ar[0][0] = "b";
$ar[1][0] = "a";
$ar[2][0] = "c";
$ar[0][1] = "2";
$ar[1][1] = "1";
$ar[2][1] = "3";

$ordArray = new OrderedMDArray($ar, 0);
print_r($ordArray->get());
?>

 

but you can also do it with the global keyword (I hate the global keyword)...

 

<?php
function cmp($a, $b)
{
global $key;
return strnatcmp($a[$key], $b[$key]);
}

$ar[0][0] = "b";
$ar[1][0] = "a";
$ar[2][0] = "c";
$ar[0][1] = "2";
$ar[1][1] = "1";
$ar[2][1] = "3";

$key = 0;
usort($ar, "cmp");
print_r($ar);
?>

 

PS. sorry, forgot the return before the strcmp() in my first reply.

it would be easiest to just change the cmp function to

 

<?php
function cmp($a, $b)
{
return strnatcmp($a[0], $b[0]);
}
?>

 

As for passing params to the function called by usort? It might be cleanest if you implement it in a class...

<?php
class OrderedMDArray {
private $array;
private $sortKey;

public function __construct($array, $sortKey) {
	$this->array = $array;
	$this->sortKey = $sortKey;
}

public function get() {
	usort($this->array, array($this, 'cmp'));
	return $this->array;
}

private function cmp($str1, $str2) {
	return strnatcmp($str1[$this->sortKey], $str2[$this->sortKey]);
}
}

$ar[0][0] = "b";
$ar[1][0] = "a";
$ar[2][0] = "c";
$ar[0][1] = "2";
$ar[1][1] = "1";
$ar[2][1] = "3";

$ordArray = new OrderedMDArray($ar, 0);
print_r($ordArray->get());
?>

 

but you can also do it with the global keyword (I hate the global keyword)...

 

<?php
function cmp($a, $b)
{
global $key;
return strnatcmp($a[$key], $b[$key]);
}

$ar[0][0] = "b";
$ar[1][0] = "a";
$ar[2][0] = "c";
$ar[0][1] = "2";
$ar[1][1] = "1";
$ar[2][1] = "3";

$key = 0;
usort($ar, "cmp");
print_r($ar);
?>

 

PS. sorry, forgot the return before the strcmp() in my first reply.

 

 

Thanks for the information. I'll give them a try.  ;)

 

HeidiR

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.