PHP Сортировка массива по алфавиту, кроме ОДНОГО значения сверху, для выпадающего меню

Я пытаюсь взломать выпадающее меню, извлекая информацию из множества стран, чтобы «Соединенные Штаты» (id 1) отображались вверху, а все остальные страны сортировались по алфавиту. Как мне отсортировать все, КРОМЕ Соединенных Штатов, чтобы оставаться на вершине, используя функцию usort для массива? Любые альтернативные предложения также приветствуются. Вот код:

while (list($key, $value) = each($countries->countries)) {
   $countries_array[] = array('id' => $key, 'text' => $value['countryname']);
}
function text_cmp($a, $b) {
   return strcmp($a["text"], $b["text"]);
} 
usort($countries_array, 'text_cmp'); 

person user2337231    schedule 01.04.2014    source источник
comment
Выполните array_shift перед сортировкой и array_unshift после.   -  person Andrew    schedule 01.04.2014
comment
вы можете проверить id==1 в text_cmp(), и в этом случае вы вернете -1   -  person Tommos    schedule 01.04.2014
comment
Не могли бы вы привести пример того, как он будет возвращен после тестирования?   -  person user2337231    schedule 01.04.2014
comment
@Andrew array_shift() будет работать только в том случае, если United States будет первым элементом, а array_unshift() приведет к потере/пересортировке всех числовых ключей.   -  person Digital Chris    schedule 01.04.2014


Ответы (3)


Самый простой способ сделать это — удалить одно значение, отсортировать, а затем снова добавить его:

рабочий пример

// your countries array goes here:
$countries = array(2=>"Burma", 4=>"Zimbabwe", 10=>"France", 1=>"United States", 13=>"Russia");

$AmericaFKYeah = array(1=>"United States");
$countries =array_diff($countries, $AmericaFKYeah);
asort($countries);

// using + instead of array_unshift() preserves numerical keys!
$countries= $AmericaFKYeah + $countries;

дает тебе:

array(5) {
  [1]=>
  string(13) "United States"
  [2]=>
  string(5) "Burma"
  [10]=>
  string(6) "France"
  [13]=>
  string(6) "Russia"
  [4]=>
  string(8) "Zimbabwe"
}
person Digital Chris    schedule 01.04.2014
comment
Извините, я немного нуб в этом... как мне сделать правильный синтаксис для массива США для целей array_diff, если мой массив стран является многоуровневым массивом? Например, я попробовал USA = array('id' => 'USD', 'text'=> 'United States');, но это возвращает Array ( [id] => USD [text] => United States ) и не соответствует массиву стран, возвращаемому как Array ( [0] => Array ( [id] => jp [text] => Japan ) [1] => Array ( [id] => USD [text] => United States ) ... и т. д. - person user2337231; 01.04.2014
comment
Ваш $countries_array кажется излишне сложным. Есть ли причина всему этому? почему бы не просто $countries_array[] = array($key=> $value['countryname']);? - person Digital Chris; 02.04.2014
comment
Я думаю, что так устроен движок OsCommerce, поскольку они используют стандартизированный синтаксис, чтобы его можно было повторно использовать в других местах... не совсем уверен. - person user2337231; 02.04.2014

С индексированным массивом

Шаги

  1. Найти ресурс в массиве
  2. Сбросить переменную в массиве
  3. Добавить ресурс в качестве первого элемента массива с помощью array_unshift (array_unshift — добавить один или несколько элементов в начало массива — http://php.net/manual/en/function.array-unshift.php)

Код

 if (in_array('yourResource', $a_array)){
    unset($a_array[array_search('yourResource',$a_array)]);
    array_unshift($a_array, 'yourResource');
 }

С многомерными массивами

$yourResorceToFind = 'yourResource';
foreach ($a_arrays as $a_sub_array){
  if (in_array($yourResorceToFind, $a_sub_array)){

    unset($a_arrays[array_search($yourResorceToFind,$a_sub_array)]);
    array_unshift($a_arrays, $a_sub_array);
    break;
  }
}
person nat_jea    schedule 27.07.2017
comment
Чтобы добавить элемент в конец массива, используйте метод push(). - person nat_jea; 20.06.2018

Я нашел эту тему, пытаясь сделать то же самое уродливым способом, но, поскольку моя техника кажется проще, я делюсь ею, если кому-то нужно.

Самый простой способ сделать это — возиться с результатом вашего обратного вызова usort. Вам просто нужно сначала передать значение, которое вы хотите, в своем обратном вызове, например:

$countries = [
 ['id' => 2, 'text' => 'Burma'],
 ['id' => 4, 'text' => 'Zimbabwe'],
 ['id' => 10, 'text' => 'France'],
 ['id' => 1, 'text' => 'United States'],
 ['id' => 13, 'text' => 'Russia'],
];

$myFirstItem = "United States";

usort($countries, function($a, $b) use ($myFirstItem) {
    return $myFirstItem == $a['text'] ? -1 : ($myFirstItem == $b['text'] ? 1 : strcmp($a['text'], $b['text']));
});

Это немного уродливо, но делает свою работу без необходимости играть с другими массивами, и все делается в обратном вызове, как и ожидалось.

person Matthieu Maudet    schedule 02.12.2019