2013-01-02 86 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) 

以上陣列表明,我們已經有了這符合我們搜索「ar」在不同的語言6個配置文件,上面說數組:

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用戶在這兩種EnglishFarsi語言= 20,但我們不能顯示2個結果同一個人!所以我們需要讓腋窩結果去,所以陣列上方應過濾和uniqued基於用戶ID和語言的優先級,我對語言的首要任務是:

  1. $ _SESSION [「my_lang」] ;
  2. 英文(en);
  3. Rand();

誰進入「ar」作爲他的搜索查詢的人有$_SESSION['my_lang'],這樣的成績數組,在$_SESSION['my_lang']結果的用戶,我們應該保持的結果,讓其他比賽中去爲同一人。

$_SESSION['my_lang']後,我們的首要任務應該是恩朗,如果一個人的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)使User數組具有唯一用戶。

note第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 V選用< 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 for 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()喜歡這個 -

$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()循環更改陣列成多用於上述步驟中的清單數組。

$users = array(); 
for($i=0;$i<count($returned);$i++){ 
    $split_returned = explode("=>",$returned[$i]); // split up each line at the '=>' 
    $users[$i]['id'] = $split_returned[0]; // set the 'id' 
    $users[$i]['lang'] = $split_returned[1];} // set the 'lang' 
+0

優秀的答案!這是要使用多少CPU/RAM!?任何想法更有效的方法來做到這一點? – behz4d

+1

不幸的是,我對CPU/Ram基準測試幫助不大,因爲我對此不甚瞭解。我使用當前數組運行了3次,運行時間相當短 - '0.000227928161621' /'0.000319004058838' /'0.000295877456665',但我不知道它對CPU/RAM使用會產生什麼影響,以及它會隨着更大的陣列而改變。此外,關於更有效的方法來實現這一點。我唯一的其他建議是找到一種方法將其添加到您的查詢中,但正如您在上面的評論中提到的那樣,您的查詢已經很複雜。所以我不確定任何其他選擇。 – Sean

+0

你會看到我更新的問題嗎?謝謝 – behz4d