想象元素数组-零售,零售,娱乐,娱乐
我需要对它们进行排序,这样彼此之间就没有重复的元素了,但是的总体订单可以是相当随机的-零售、娱乐、零售、娱乐。
我尝试过 uasort (),但无法退出查找从何处开始,因为它将比较所有可能的对,我认为我希望存储在外部数组中已经检查过的元素,以知道在哪种情况下返回-或+整数,是否可以移动多个位置,即返回-2;或在异步回调中搜索
输入阵列$input = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];
输出数组应该类似于$output = ['Retail', 'Food', 'Retail', 'Charity', 'Entertainment', 'Transport', 'Entertainment', 'Cosmetics'];
我的尝试:
<?php
$input = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];
$sorted = [];
uasort(
$input,
static function ($a, $b) use (&$sorted) {
$is_a_sorted = in_array($a, $sorted, true);
$is_b_sorted = in_array($b, $sorted, true);
switch (true) {
case !$is_a_sorted && !$is_b_sorted:
$sorted[] = $a;
$sorted[] = $b;
return -1;
case $is_a_sorted || $is_b_sorted:
return 1;
default:
return 0;
}
}
);
print_r($input);
其结果是:
阵列(7 =>化妆品4 =>娱乐6 =>传输5 =>娱乐2 =>食品3 =>慈善=>零售1 =>零售)
发布于 2020-08-25 13:24:39
受此链接的启发,我决定将数据压缩为一个值和计数的关联数组,然后将数组从大多数排序到最少。我循环遍历数组,只处理第一个元素。我将值添加到输出数组中,然后减少其计数,并将其移到下一个元素之后的位置。
我已经建立了一个故障安全,以防止无限循环时,一个完美的结果是不可能的。
如果没有超过一次的值,则不会输入该循环。
代码:(演示)
function valueSeparator(array $array) {
$maxIterations = count($array);
$counted = array_count_values($array);
arsort($counted);
$iteration = 0;
$result = [];
while (max($counted) > 1 && $iteration < $maxIterations) {
$count = reset($counted);
$value = key($counted);
$result[] = $value;
unset($counted[$value]);
arsort($counted);
if ($count > 1) {
$counted = array_merge(
array_splice($counted, 0, 1),
[$value => $count - 1],
$counted
);
}
++$iteration;
}
array_push($result, ...array_keys($counted));
var_export($result);
}
foreach ($arrays as $array) {
valueSeparator($array);
echo "\n---\n";
}
测试用例:
$arrays = [
['Retail', 'Retail', 'Food', 'Food', 'Retail'],
['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'],
['Food'],
['Retail', 'Retail', 'Food', 'Retail'],
['Retail', 'Retail', 'Retail', 'Food', 'Food', 'Food', 'Charity', 'Charity', 'Charity'],
['Charity', 'Entertainment', 'Retail', 'Retail' ,'Retail']
];
产出:
array (
0 => 'Retail',
1 => 'Food',
2 => 'Retail',
3 => 'Food',
4 => 'Retail',
)
---
array (
0 => 'Retail',
1 => 'Entertainment',
2 => 'Food',
3 => 'Retail',
4 => 'Entertainment',
5 => 'Charity',
6 => 'Transport',
7 => 'Cosmetics',
)
---
array (
0 => 'Food',
)
---
array (
0 => 'Retail',
1 => 'Food',
2 => 'Retail',
3 => 'Retail',
)
---
array (
0 => 'Retail',
1 => 'Food',
2 => 'Charity',
3 => 'Retail',
4 => 'Food',
5 => 'Charity',
6 => 'Retail',
7 => 'Food',
8 => 'Charity',
)
---
array (
0 => 'Retail',
1 => 'Charity',
2 => 'Retail',
3 => 'Entertainment',
4 => 'Retail',
)
---
发布于 2020-08-25 10:30:02
我找到了一种分类方法,也许任何人都有更好的想法:
<?php
$array = ['Retail', 'Retail', 'Food', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];
$sorted = [];
while (!empty($array)) {
$current = current($array);
if (end($sorted) !== $current) {
$sorted[] = $current;
array_splice($array, key($array), 1);
}
$next = next($array);
if (!$next) {
reset($array);
shuffle($array);
}
}
print_r($sorted);
输出:
Array
(
[0] => Retail
[1] => Food
[2] => Charity
[3] => Entertainment
[4] => Transport
[5] => Entertainment
[6] => Cosmetics
[7] => Retail
)
另一个输入示例:
$array = ['Retail', 'Retail', 'Retail', 'Retail', 'Retail', 'Food', 'Charity', 'Charity', 'Charity', 'Entertainment', 'Entertainment', 'Transport', 'Cosmetics'];
输出:
Array
(
[0] => Retail
[1] => Food
[2] => Retail
[3] => Charity
[4] => Retail
[5] => Charity
[6] => Retail
[7] => Charity
[8] => Entertainment
[9] => Transport
[10] => Entertainment
[11] => Cosmetics
[12] => Retail
)
在特殊情况下更新代码,如输入类似于['Retail', 'Retail', 'Food', 'Retail']
,在我的情况下,这是可信和可接受的:
<?php
$array = ['Retail', 'Retail', 'Food', 'Retail'];
$sorted = [];
$tries = 0;
$maxTries = count($array);
while (!empty($array) && $tries <= $maxTries) {
$current = current($array);
if (end($sorted) !== $current) {
$sorted[] = $current;
array_splice($array, key($array), 1);
}
$next = next($array);
if (!$next) {
reset($array);
shuffle($array);
$tries++;
}
}
if (!empty($array)) {
array_push($sorted, ...$array);
}
print_r($sorted);
产出:
Array
(
[0] => Retail
[1] => Food
[2] => Retail
[3] => Retail
)
发布于 2020-08-26 07:12:30
我试着将排序数组保持在输入数组附近。首先,我从数组中删除任何不合适的元素,然后尝试在以后插入它们。如果留下任何元素,我将遍历数组,将它们插入任何合适的位置,避免无休止的循环。结果得到两个数组,一个排序,一个找不到合适的位置:
$input = ['Charity','Retail','Retail','Retail','Retail', 'Retail' ,'Retail', 'Charity', 'Charity', 'Charity','a' ];
$laRest = [];
$sorted = [];
$laNoPlace = [];
while(count($input) >0) {
for ($i = 0; $i < count($laRest); $i++) {
if(isset($laRest[$i]) && $laRest[$i] != end($sorted)) {
$sorted[] = $laRest[$i];
unset($laRest[$i]);
}
}
$laRest = array_values($laRest);
$lsElement = array_shift($input);
if (end($sorted) != $lsElement) {
$sorted[] = $lsElement;
}
else {
$laRest[] = $lsElement;
}
}
if(count($laRest) >0) {
while(count($laRest) >0) {
$lsElement = array_shift($laRest);
for ($i = 0; $i < count($sorted); $i++) {
if($i != 0 && $sorted[$i] != $lsElement && !isset($sorted[$i+1]) && $lsElement !='') {//end
array_push($sorted, $lsElement);
$lsElement = '';
}
if($i != 0 && $sorted[$i] != $lsElement && isset($sorted[$i+1]) && $sorted[$i+1] != $lsElement && $lsElement !='') {
$lsStart = array_slice($sorted, 0, $i+1);
$lsEnd = array_slice($sorted , $i+1);
$sorted = array_merge($lsStart, array($lsElement), $lsEnd);
$lsElement = '';
}
if($i == 0 && $sorted[$i] != $lsElement && $lsElement !='') {//start
array_unshift($sorted, $lsElement);
$lsElement = '';
}
}
if($lsElement != '') {
$laNoPlace[] = $lsElement;
}
}
}
print_r($sorted);
echo "<HR>";
print_r($laNoPlace);
echo "<HR>";
https://stackoverflow.com/questions/63575906
复制相似问题