2013-01-02 2 views
1

На моем сайте пользователи могут публиковать свой профиль на разных языках, что-то вроде LinkedIn, теперь мы ищем между первым именем пользователей, например, мы ищем: 'ar', и мы изучаем все профили языков, мы будем иметь массив в ответе, как:PHP-массивы - сортировка и приоритет

array 
    0 => string '20=>en' (length=5) 
    1 => string '42=>en' (length=5) 
    2 => string '20=>fa' (length=5) 
    3 => string '42=>sp' (length=5) 
    4 => string '12=>fr' (length=5) 
    5 => string '83=>ar' (length=5) 
    6 => string '160=>sp' (length=5) 

выше массив показывает, что у нас есть 6 профилей, совпадающие наш поиск «ar» на разных языках, выше массив говорит:

0 => Match found for User with ID = 20 in English Lang(en) profile 
1 => Match found for User with ID = 42 in English Lang(en) profile 
2 => Match found for User with ID = 20 in Farsi Lang(fa) profile 
3 => Match found for User with ID = 42 in Spanish Lang(sp) profile 
4 => Match found for User with ID = 12 in French Lang(fr) profile 
5 => Match found for User with ID = 83 in Arabic Lang(ar) profile 
6 => Match found for User with ID = 160 in Spanish Lang(sp) profile 

Теперь мы хотим показать результаты, но, по сути, как вы видите в результатах, у нас есть совпадения для «ar» для пользователя с ID = 20 в обоих English и Farsi языках, но мы не можем показать 2 результата тот же человек! поэтому мы должны отпустить результаты подмышечных, поэтому массив выше должен быть отфильтрован и uniqued на основе идентификаторов пользователей и приоритетом языков, мой приоритет для языков:

  1. $ _SESSION [ «my_lang»] ;
  2. английский язык (en);
  3. Rand();

Человек, который входит в «ar», как его поисковый запрос имеет $_SESSION['my_lang'], поэтому в массиве результатов для пользователя, который имеет результаты в $_SESSION['my_lang'] мы должны держать, что результаты и отпустить остальных матчей для одного человека ,

После $_SESSION['my_lang'], наш приоритет должен быть EN Ланг, если человек имеет результаты на N языках, но мы не могли нашли матч в $_SESSION['my_lang'], то мы должны сохранить результаты в ан языке и ясно, что остальная часть результатов для этого человека.

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

Я понятия не имею, как это можно сделать, Буду признателен за любую помощь.


В моем примере, у меня есть массив, как:

array 
    0 => string '20=>en' (length=5) 
    1 => string '42=>en' (length=5) 
    2 => string '20=>fa' (length=5) 
    3 => string '42=>sp' (length=5) 
    4 => string '12=>fr' (length=5) 
    5 => string '83=>ar' (length=5) 
    6 => string '160=>sp' (length=5) 

, но в вашем примере, у вас есть массив, как:

$users = array(
    array('id'=> 20, 'lang'=>'en'), 
    array('id'=> 42, 'lang'=>'en'), 
    array('id'=> 20, 'lang'=>'fa'), 
    array('id'=> 42, 'lang'=>'sp'), 
    array('id'=> 12, 'lang'=>'fr'), 
    array('id'=> 83, 'lang'=>'ar'), 
    array('id'=> 160, 'lang'=>'sp')); 

Как я должен сделать мой массив, чтобы посмотреть как ваш массив, так что ваши коды работают ..? Спасибо

+2

Похоже, что вы можете включить это ограничение/порядок в то, что выполняет поисковый запрос, а не на возвращаемый массив данных. –

+0

@MattRazza Поисковый запрос действительно очень сложный, я просто понял, что со многими объединениями и фильтрацией ... Я предпочитаю ограничивать результаты, любую идею? – behz4d

ответ

1

Есть, вероятно, лучшие (более эффективные) способы сделать это, но вот один из способов. Делать это в 3 шага. (1) Создайте языковой массив, (2) упорядочите массив пользователей, основываясь на массиве языков, (3) сделайте массив пользователя уникальными.

примечание Этап 2 использует анонимные функции, поэтому, если PHP v < 5.3, использовать второй шаг 2 Пример

Массив пользователей

$users = array(
       array('id'=> 20, 'lang'=>'en'), 
       array('id'=> 42, 'lang'=>'en'), 
       array('id'=> 20, 'lang'=>'fa'), 
       array('id'=> 42, 'lang'=>'sp'), 
       array('id'=> 12, 'lang'=>'fr'), 
       array('id'=> 83, 'lang'=>'ar'), 
       array('id'=> 160, 'lang'=>'sp')); 

Шаг 1

//Create an Array of Languages 
$langs[0] = $_SESSION['my_lang']; // Set $_SESSION['my_lang'] as 1st 
if($langs[0] != 'en'){ 
    $langs[1] = 'en';} // Set en as 2nd, if not already as 1st 

//Add remainder of User languages to Languages 
shuffle($users); // This randomizes the $user array so the rest of the languages are random. Can be removed if randomizing the rest of the languages is not necessary. 
foreach ($array as $lang) { 
    if(!in_array($lang['lang'],$langs)) 
     $langs[] =$lang['lang']; 
} 

Шаг 2 использовать с PHP V> = 5.3 - использует анонимные функции

//Reorder the User array, bases off Language array 
$keys = array_flip($langs); 
usort($users, function($a, $b) use($keys) 
{ 
    return $keys[$a['lang']] - $keys[$b['lang']]; 
}); 

Шаг 2 использование с PHP против < 5,3

//Reorder the User array, bases off Language array 
$keys = array_flip($langs); 
function custom($a,$b){ 
    global $keys; 
    return $keys[$a['lang']] - $keys[$b['lang']]; 
} 
usort($users, "custom"); 

Шаг 3

//Make the User array unique 
$temp_array = array(); 
foreach ($users as &$v) { 
    if (!isset($temp_array[$v['id']])) 
     $temp_array[$v['id']] =&$v; 
} 
$users = array_values($temp_array); 

phpFiddle ж/шаг 2 для PHP V> = 5,3 - http://phpfiddle.org/main/code/xva-dzn

phpFiddle ж/Этап 2 для php v < 5.3 - http://phpfiddle.org/main/code/p02-r6b


Редактировать
Предполагая, что ваш массив -

array 
    0 => string '20=>en' (length=5) 
    1 => string '42=>en' (length=5) 
    2 => string '20=>fa' (length=5) 
    3 => string '42=>sp' (length=5) 
    4 => string '12=>fr' (length=5) 
    5 => string '83=>ar' (length=5) 
    6 => string '160=>sp' (length=5) 

является var_dump() что-то вроде this-

$returned = array(
    0 => '20=>en', 
    1 => '42=>en', 
    2 => '20=>fa', 
    3 => '42=>sp', 
    4 => '12=>fr', 
    5 => '83=>ar', 
    6 => '160=>sp'); 

Использование explode() и for() петли изменить массив в многоуровневый массив, который будет использоваться на вышеуказанных этапах.

+0

Отличный ответ! это будет использовать много CPU/Ram !? любые идеи для более эффективных способов сделать это? – behz4d

+1

К сожалению, я не могу много помочь с бенчмаркингом CPU/Ram, так как я не очень разбираюсь в этом. Я запускал его 3 раза с текущим массивом, а время запуска было довольно небольшим - '0.000227928161621' /' 0.000319004058838'/'0.000295877456665', но я не знаю, какой эффект он имел бы при использовании CPU/Ram, а также как это изменилось бы с большими массивами. Кроме того, в отношении более эффективных способов достижения этого. Мое единственное другое предложение - найти способ добавить его к вашему запросу, но, как вы упомянули в комментарии выше, ваш запрос уже сложный. Поэтому я не уверен в других вариантах. – Sean

+0

не могли бы вы увидеть мой обновленный вопрос? спасибо – behz4d

Смежные вопросы