#php #arrays
#php #массивы
Вопрос:
Итак, в настоящее время у меня есть это:
array(0=>'foo', 1=>'bar', 3=>'baz', 4=>'boo', 5=>'wahoo');
Чего я хочу, так это:
array(0=>'foo', 3=>'baz', 1=>'bar', 5=>'wahoo', 4=>'boo');
Это упрощенный пример, мой фактический массив намного больше и сложнее, поэтому его нелегко разбить на более мелкие части и собрать заново.
Я использовал uksort, чтобы попытаться это сделать, что, я думаю, является лучшим способом продвижения вперед, но, похоже, не могу получить желаемые результаты.
Редактировать:
Я думаю, что мой упрощенный пример на самом деле запутывает проблему. Вот мой фактический массив и то, что я хочу получить в итоге.
Array
(
[1820] => Safety
[1821] => Security
[1822] => Digital Life
[1893] => Privacy and Digital Footprints
[1823] => Connected Culture
[1824] => Respecting Creative Work
[1825] => Searching
[1826] => Research and Evaluation
[1836] => Self-Expression and Identity
)
Array
(
[1820] => Safety
[1821] => Security
[1822] => Digital Life
[1893] => Privacy and Digital Footprints
[1823] => Connected Culture
[1836] => Self-Expression and Identity
[1824] => Respecting Creative Work
[1825] => Searching
[1826] => Research and Evaluation
)
Итак, у меня почти есть числовая сортировка с двумя элементами, вырванными из последовательности.
Комментарии:
1. Это числовой или ассоциативный массив?
2. @Jared — как только ключи выходят из строя, это ассоциативно (технически это всегда ассоциативно с некоторой специальной обработкой, когда php видит числа).
3. Каковы критерии сортировки? Например. Почему baz должен быть перед bar, а boo за wahoo?
4. Есть ли какая-либо логика в порядке ваших элементов? Или вы хотите вручную изменить порядок некоторых элементов на любую позицию, которую вы хотите, сохраняя при этом их ключи?
5. В этом случае я настоятельно рекомендую создать лучший вопрос, который гораздо точнее отражает то, что вы хотите сделать. Вот несколько других вариантов: во-первых, используйте то, что здесь, и сделайте функцию сравнения осведомленной о приоритетах каждого элемента. Во-вторых, измените структуру данных, включив приоритеты и сортировку по ним в функцию сравнения.
Ответ №1:
На самом деле вы ищете uasort.
Это позволит вам использовать вашу собственную функцию сортировки и сохранить ключи.
uksort
сортирует на основе ключей, а не значений.
Пример:
http://codepad.viper-7.com/E8oZ2g
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
// Array to be sorted
$array = array('a', 'b', 'c', 'b');
echo "<pre>";
print_r($array);
echo "</pre>";
// Sort and print the resulting array
uasort($array, 'cmp');
echo "<pre>";
print_r($array);
echo "</pre>";
Вывод:
Array
(
[0] => a
[1] => b
[2] => c
[3] => b
)
Array
(
[0] => a
[3] => b
[1] => b
[2] => c
)
Комментарии:
1. Сохранит ли это числовые индексы?
2. В примере ключи перемещаются вместе со значениями. Это то, что делает uasort см. добавленный пример.
3. Верно (как вы видите, мне было интересно об этом). Единственное, что я бы добавил, это
foreach()
то, что для доступа к порядку нового массива требуется цикл: codepad.viper-7.com/kQuwis . (И я бы предпочел, чтобы ваш код тоже был в ответе, а не только на странице codepad, но1
в любом случае.)4. итак, если я хочу получить
code
array(0 => ‘foo’, 5 => ‘wahoo’, 1 =>’bar’, 3 => ‘baz’, 4 => ‘boo’);code
в качестве конечного результата с использованием uasort, как мне поступить. Насколько я понимаю,code
if($ a == ‘wahoo’) return -1code
должен плавно перемещаться до самого верха, но как мне остановиться в определенной точке?5. Вы не можете «остановить» сортировку. Если у вас есть какой-то специальный алгоритм, который выполняет сортировку, вы помещаете его в качестве функции сравнения. Но это должно работать при сравнении каждого значения с каждым другим значением.
Ответ №2:
Новый ответ, основанный на обсуждении.
Используйте uksort()
Выполните переключение в функции сравнения для совпадающих и измените их.
Пример, который работает для вашего примера выше.
function updateKey($key)
{
switch($key)
{
case 1893:
return 1822.5;
case 1836:
return 1823.5;
default:
return $key;
}
}
function cmp($a, $b)
{
$a = updateKey($a);
$b = updateKey($b);
// you must do the compare this way for floats (instead of just subtracting) because php implemented the compare callback poorly
if ($a == $b)
{
return 0;
}
return ($a < $b) ? -1 : 1;
}
uksort($array, 'cmp');
Ответ №3:
//randomize array preserving keys
function shuffle_assoc( $array )
{
$keys = array_keys( $array );
shuffle( $keys );
return array_merge( array_flip( $keys ) , $array );
}
Источник: http://www.php.net/manual/en/function .shuffle.php
Обратите внимание, что это возвращает новый массив, он не изменяет входной массив.
Комментарии:
1. Извините, я думаю, что случайный в названии отбросил его, элементы, которые перемещаются, важны. Я имел в виду, что результирующий порядок никоим образом не был предсказуем.
2. Какую формулу или функцию вы хотите использовать для перехода от исходного массива к результирующему массиву? они отсортированы в каком-либо определенном порядке или вы просто назначаете их вручную?