2017-07-31 30 views
1

我有以下陣列,其包括ID:什麼是一個更好的方式來替換數組中的ID與它們的值對應?

[Key1] => 1 
[Key2] => 2, 3 

我想通過它們各自的名稱從該第二陣列來取代這些ID:

[0] => Array 
    (
     [ID] => 1 
     [Name] => Name1 
    ) 

[1] => Array 
    (
     [ID] => 2 
     [Name] => Name2 
    ) 

[2] => Array 
    (
     [ID] => 3 
     [Name] => Name3 

所需的輸出:

[Key1] => Name1 
[Key2] => Name2, Name3 

我有下面的代碼,但我知道這不是正確的方法。如果有人能讓我知道什麼是更好的方式來實現這一點,將不勝感激。

什麼我的代碼如下所示:

$var1 = explode(", ", $array1["Key1"]); // No need to explode in this example but "Key1" sometimes includes more than 1 ID 
$var2 = explode(", ", $array1["Key2"]); 

$array1["Key1"] = $var1 ; // This row is for the new array generated from "explode" to be a sub-array 
$array1["Key2"] = $var2 ; // Same 

for ($i = 0; $i < 83; $i++){ 
    if($array1["Key1"][0] == $array2[$i]["ID"]){ 
     $array1["Key1"][0] = $array2[$i]["Name"]; 
    } 
    if($array1["Key1"][1] == $array2[$i]["ID"]){ 
     $array1["Key1"][1] = $array2[$i]["Name"]; 
    } 
// (etc) 
    if($array1["Key2"][0] == $array2[$i]["ID"]){ 
     $array1["Key2"][0] = $array2[$i]["Name"]; 
    } 
    if($array1["Key2"][1] == $array2[$i]["ID"]){ 
     $array1["Key2"][1] = $array2[$i]["Name"]; 
    } 
// (etc) 

} 

$var1 = implode(", ", $array1["Key1"]); 
$var2 = implode(", ", $array1["Key2"]); 

$array1["Key1"] = $var1 ; 
$array1["Key2"] = $var2 ; 
+0

Adrien檢查下面的答案。 –

+0

哇!有人討厭所有的答案。 – AbraCadaver

+0

奇怪的是,有人沒有任何解釋就低估了所有的答案。非常感謝所有花時間回答我的問題的人,今晚我會做一些測試:)! – Adrien

回答

2

只需提取的IDName成一維,並用它作爲搜索和替換參數。我們需要修改ID s到搜索,並把它們變成一個模式/\b$v\b/其中\b是一個單詞邊界,使1不會164更換1例如:

$replace = array_column($array2, 'Name', 'ID'); 
$search = array_map(function($v) { return "/\b$v\b/"; }, array_keys($replace)); 

$array1 = preg_replace($search, $replace, $array1); 
+0

我真的很喜歡你的想法AbraCadaver,但我遇到了一個小問題。例如,如果我們有'164'作爲ID,它會將ID標識爲'1'並將其替換爲一個名稱,最後將64替換爲我的列表中的6,4或64不是我的列表中的ID。因此,即使存在ID164,ID164也被接着數字64的ID1所對應的名稱替換。任何想法如何解決這個問題? – Adrien

+0

好的。我用'preg_replace'和一個查找單詞邊界的模式修復。 – AbraCadaver

+0

這現在就像一個魅力,非常感謝;)! – Adrien

2

你需要一些嵌套循環。這裏是一個sample應該工作:

//Processing Array 
$arrayOne = array(
    "Key1" => "1", 
    "Key2" => "2, 3"); 

//Lookup Array 
$arrayTwo = array(
    array(
     "ID" => "1", 
     "Name" => "Name1"), 
    array(
     "ID" => "2", 
     "Name" => "Name2"), 
    array(
     "ID" => "3", 
     "Name" => "Name3")); 

var_dump($arrayOne); 

//Loop through all values in our original array 
foreach($arrayOne as &$arrValue) { 
    //Split the value in the original array into another temporary array 
    //if there are multiple values. 
    $valueArray = explode(", ", $arrValue); 
    $outputArray = array(); 
    foreach($valueArray as &$myValue) { 
     //Now do a lookup to replace each value 
     foreach($arrayTwo as &$lookupValue) { 
      //Find a match 
      if($myValue==$lookupValue["ID"]) { 
       $myValue = $lookupValue["Name"]; 
       //We found the value we want, so let's break out of this loop 
       break; 
      } 
     } 
     //Append the value 
     array_push($outputArray, $myValue); 
    } 
    //Convert back to string 
    $arrValue= implode(", ", $outputArray); 
} 

var_dump($arrayOne); 

有改進,你可能對這個代碼,如果你輸入的數據總是排序,但我想這還只是針對上述您的樣品的情況。

2

我有一個方法來做到這一點。如果您想在這裏看到: - https://eval.in/839823,您可以試試。我正在使用array_column來映射鍵=>值對,然後簡單地使用foreach

<?php 
$main = ['Key1' => 1,'Key2' => '2, 3']; 

$match = [ 
    [ 
     'ID' => 1, 
     'Name' => 'Name1' 
    ], 

    [ 
     'ID' => 2, 
     'Name' => 'Name2' 
    ], 
    [ 
     'ID' => 3, 
     'Name' => 'Name3' 
    ] 
]; 

$final_array=[]; 
$mapped = array_column($match, 'Name', 'ID'); 
foreach($main as $k=>$v){ 
    $r = explode(',',$v); 
    if(count($r)>1){ 
     $final_array[$k] = $mapped[$r[0]]. ", ".$mapped[intval($r[1])]; 
    }else{ 
     $final_array[$k] = $mapped[$r[0]]; 
    } 
}  
print '<pre>'; 
//print_r($mapped); 
print_r($final_array); 
print '</pre>'; 

輸出:

Array 
(
    [Key1] => Name1 
    [Key2] => Name2,Name3 
) 

編輯:按照喬希馬格的評論,

如果他只在最多2個值的我的代碼只會工作KEY2。 如果Key3包含「4,5,6」,則此代碼將使6不受影響。

<?php 


$main = ['Key1' => 1,'Key2' => '2,3','Key3' => '4,5,6']; 

    $match = [ 
     [ 
      'ID' => 1, 
      'Name' => 'Name1' 
     ], 

     [ 
      'ID' => 2, 
      'Name' => 'Name2' 
     ], 
     [ 
      'ID' => 3, 
      'Name' => 'Name3' 
     ], 
     [ 
      'ID' => 4, 
      'Name' => 'Name4' 
     ], 
     [ 
      'ID' => 5, 
      'Name' => 'Name5' 
     ], 
     [ 
      'ID' => 6, 
      'Name' => 'Name6' 
     ] 
    ]; 

    $final_array=[]; 
    $mapped = array_column($match, 'Name', 'ID'); 
    foreach($main as $k=>$v){ 
     $r = explode(',',$v); 
     if(count($r)>1){ 
      $final_array[$k] = implode(',',array_map(function($key) use ($mapped){ return $mapped[$key]; }, array_values($r))); 
     }else{ 
      $final_array[$k] = $mapped[$r[0]]; 
     } 
    }  

    print '<pre>'; 
    print_r($mapped); 
    print_r($final_array); 
    print '</pre>'; 
    ?> 

觀看演示看到這裏https://eval.in/839939

+0

正在陽光下,只有在Key2中只有最多2個值的情況下,您的解決方案才能正常工作。如果Key3包含「4,5,6」,則此代碼將使6不受影響。 –

+0

@JoshMaag請看看我的編輯:) –

0

的核心功能應該用於此任務preg_replace_callback()。爲什麼?因爲它是唯一有資格在單個函數調用中處理此操作。不使用php函數來設計他們的目的似乎是一個悲劇。

超出preg_replace_callback(),只需要array_column()即可將$array2數據準備爲簡單的查找數組。

代碼:(Demo

$array1=["Key1"=>"1","Key2"=>"22, 4, 123"]; 
$array2=[["ID"=>"1","Name"=>"Name1"],["ID"=>"22","Name"=>"Name22"],["ID"=>"123","Name"=>"Name123"]]; 
$lookup=array_column($array2,'Name','ID'); // generate array: keys = IDs, vals = Names 

$result=preg_replace_callback('/\d+/',function($m)use($lookup){return isset($lookup[$m[0]])?$lookup[$m[0]]:"*{$m[0]}*";},$array1); 
var_export($result); 

輸出:

array (
    'Key1' => 'Name1', 
    'Key2' => 'Name22, **4**, Name123', 
) 

無需運行任何準備使用額外的循環或函數調用(不包括$lookup)。

此模式將匹配$array1中每個元素的所有完整ID數字,並對它們進行單獨處理。每個數字匹配都會發送到匿名回調函數以接收由$lookup數據傳遞的定製替換字符串。

作爲一個額外的考慮,我在$lookup中找不到ID時包含了一個星號包裝的替換。

+0

@Adrien如果我不是很確定這是一個優於所有其他答案的方法,我不會爲這篇晚期文章而煩心。我的'preg_replace_callback()'是你(以及所有將來的SO讀者)應該用於這項任務的方法。如果您對此功能有疑問,請詢問我。 – mickmackusa

相關問題