目前我有一个包含不同位置的x和y坐标的数组。
离。
$location[0]['x'] = 1; $location[0]['y'] = 1
这表示id 0的位置为(1,1)。
有时我想用x对这个数组进行排序,其他时候用y。
目前我正在使用array_multisort()
对数据进行排序,但我觉得这种方法效率很低,因为每次排序之前,我必须通过$location
数组进行线性传递才能构建索引(在x或y键上)我可以调用array_multisort()
命令。
有谁知道更好的方法吗?即使存储这样的数据也许是一个坏主意?任何建议都会很棒。
答案 0 :(得分:2)
您可以使用usort()来选择数组元素的比较方式。
// sort by 'y'
usort($location, 'cmp_location_y');
// or sort by 'x'
usort($location, 'cmp_location_x');
// here are the comparison functions
function cmp_location_x($a, $b) {
return cmp_location($a, $b, 'x');
}
function cmp_location_y($a, $b) {
return cmp_location($a, $b, 'y');
}
function cmp_location($a, $b, $key) {
if ($a[$key] == $b[$key]) {
return 0;
} else if ($a[$key] < $b[$key]) {
return -1;
} else {
return 1;
}
}
答案 1 :(得分:2)
您希望继续使用多重排序。
我对usort和array_multisort做了快速基准测试。即使只有10个多重排序,建立索引也比usort快。在100个元素,它大约快5倍。大约1000个元素的改进水平正好更快。用户函数调用太慢了。我正在运行5.2.6
$count = 100;
for ($i = 0; $i < $count; $i++)
{
$temp = array('x' => rand(), 'y' => rand());
$data[] = $temp;
$data2[] = $temp;
}
function sortByX($a, $b) { return ($a['x'] > $b['x']); }
$start = microtime(true);
usort($data, "sortByX");
echo (microtime(true) - $start) * 1000000, "<br/>\n";
$start = microtime(true);
foreach ($data2 as $temp)
$s[] = $temp['x'];
array_multisort($s, SORT_NUMERIC, $data2);
echo (microtime(true) - $start) * 1000000, "<br/>\n";
PHP目前没有像ruby这样的array_pluck函数。完成后,您可以替换此代码
foreach ($data2 as $temp)
$s[] = $temp['x'];`
与
$s = array_pluck('x', $data2);
答案 2 :(得分:0)
像jcinacio所说的那样。通过这个类,您可以真正存储和排序各种数据,而不仅仅是不同维度的位置。您可以根据需要实现其他方法,例如删除等。
class Locations {
public $locations = array();
public $data = array();
public $dimensions = 2;
public function __construct($dimensions = null)
{
if (is_int($dimensions))
$this->dimensions = $dimensions;
}
public function addLocation()
{
$t = func_num_args();
if ($t !== $this->dimensions)
throw new Exception("This Locations object has {$this->dimensions} dimensions");
$args = func_get_args();
for ($i = 0; $i < $t; $i++)
$this->locations[$i][] = $args[$i];
return $this;
}
public function sortByDimension($dimension = 1)
{
if ($dimension > $this->dimensions)
throw new Exception("Wrong number of dimensions");
--$dimension;
$params[] = &$this->locations[$dimension];
for ($i = 0, $t = $this->dimensions; $i < $t; $i++) {
if ($i === $dimension)
continue;
$params[] = &$this->locations[$i];
}
call_user_func_array('array_multisort', $params);
return $this;
}
}
测试数据:
$loc = new Locations(3);
$loc
->addLocation(1, 1, 'A')
->addLocation(2, 3, 'B')
->addLocation(4, 2, 'C')
->addLocation(3, 2, 'D')
;
$loc->sortByDimension(1);
var_dump($loc->locations);
$loc->sortByDimension(2);
var_dump($loc->locations);
答案 3 :(得分:-1)
保留你拥有的数组和多重排序,将结构更改为类似以下的内容将消除前一次传递的需要:
$locations = array(
'x' => $x_coordinates,
'y' => $y_coordinates,
'data' => $data_array
);
然后在所有列上使用array_multisort()。