用对应的值替换数组中的 ID 的更好方法是什么?

What is a better way to replace IDs in an array with their value counterpart?

我有以下包含 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 ;

您需要嵌套一些循环。这是一个应该有效的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);

如果您的传入数据始终排序,您可能会对此代码进行改进,但我想这只是您上面示例的情况。

我有办法做到这一点。如果您想在此处查看,可以尝试一下:- https://eval.in/839823. I am using array_column to map the key=>value pair and then simple used 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
)

编辑 :根据 Josh Maag

的评论

My code will only work if he only has a maximum of 2 values in Key2. If Key3 contains "4,5,6" this code will leave the 6 untouched.

<?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

只需将 IDName 提取到一个维度中,并将其用作搜索和替换参数。我们需要修改 ID 来搜索并将它们变成一个模式 /\b$v\b/ 其中 \b 是一个单词边界,这样 1 就不会替换 1164 例如:

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

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

应该用于此任务的核心函数是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 时,我已经包括了一个星号包裹的替代品