我在数组中有以下值,
$values = array(
"1/4x1/4x1",
"1/2x1/2x1",
"3/4x3/4x1",
"1/4x1/4x2",
"1/2x1/2x2",
"3/4x3/4x2",
"1x1x1",
"1x2x1",
"2x1x1"
);
考虑到'x'之间的数字,我希望值的升序如下,
$values = array(
"1/4x1/4x1",
"1/4x1/4x2",
"1/2x1/2x1",
"1/2x1/2x2",
"3/4x3/4x1",
"3/4x3/4x2",
"1x1x1",
"1x2x1",
"2x1x1"
);
我是PHP的新手。这有什么特定的功能吗?如果没有,请帮助找到解决方案。感谢。
答案 0 :(得分:0)
这有点复杂,但您可以避免使用eval
:
// Transpose resulting 2x2 matrix using array_map behavior of
// tacking an arbitrary number of arrays and zipping elements, when null
// giving as a callback.
$evaluated = array_map(null, ...array_map(function ($factors) {
return array_map(function ($factor) {
// Explode fraction (into array with two elements)
// and destruct it into variables.
// `@` will silent the notice if not a fraction given (array with one
// element).
@list($dividend, $divisor) = explode('/', $factor); // **
// If divisor is given then calculate a fraction.
return $divisor
? floatval($dividend) / floatval($divisor)
: floatval($dividend);
}, explode('x', $factors));
}, $values));
// Assign values array by reference as a last element.
$evaluated[] =& $values;
// Unpack all arrays (three columns of fractions and given array) and pass
// them to `array_multisort` function, that will sort in turns by each of
// the columns.
array_multisort(...$evaluated);
print_r($values);
因此,基本上,我们将数组中的每个项目映射到计算分数的数组中,然后转换此数组,最后得到三个表示列的数组。然后我们将这三个数组与给定数组一起传递给array_multisort
,它通过引用获取给定数组并根据需要重新排序。
这是the demo。
答案 1 :(得分:0)
不要使用eval()
!这是邪恶的。你可以轻松地避免它。您需要为usort()创建一个回调方法,用于比较维度(如果需要,可以将分数转换为数值)。
我假设你总是有3个维度,它们是正整数或分数。我还假设您没有按体积排序,而是按尺寸1,尺寸2,尺寸3进行排序。
/**
* usort callback to sort dimensions
* @param {string} $a first comparable value
* @param {string} $b second comparable value
* @returns {int} 0, 1 or -1
*/
function sortByDimension($a, $b) {
$dimA = getNumericDimensions($a);
$dimB = getNumericDimensions($b);
// first dimension is the same: compare deeper
if ($dimA[0] == $dimB[0]) {
// second dimension is the same too: compare deeper
if ($dimA[1] == $dimB[1]) {
if ($dimA[2] == $dimB[2]) {
// value is the same: return 0
return 0;
}
// value A is larger: return 1, value B is larger: return -1
return ($dimA[2] > $dimB[2]) ? 1 : -1;
}
return ($dimA[1] > $dimB[1]) ? 1 : -1;
}
return ($dimA[0] > $dimB[0]) ? 1 : -1;
}
/**
* converts a string value to an array of numeric values
* @param {string} $val string of dimensions AxBxC
* @returns {array} an array with 3 dimensions and numeric values
*/
function getNumericDimensions($val) {
// split the value into the 3 dimensions
$dimensions = explode('x', $val);
// loop through the values and make them numeric
// note: the loop is per reference: we override the values!
foreach ($dimensions as &$dim) {
// check if it is a fraction
if (strpos($dim, '/') !== false) {
// split the fraction by the /
$fraction = explode('/', $dim);
// calculate a numeric value
$dim = $fraction[0] / $fraction[1];
} else {
// make it an integer
$dim = (int)$dim;
}
}
return $dimensions;
}
$values = array(
"1/4x1/4x1",
"1/2x1/2x1",
"3/4x3/4x1",
"1/4x1/4x2",
"1/2x1/2x2",
"3/4x3/4x2",
"1x1x1",
"1x2x1",
"2x1x1",
);
// sort the array (note: usort is per reference)
usort($values, 'sortByDimension');
print_r($values);