首页 > 解决方案 > 保留另一个数组中的键 array_splice

问题描述

我试图从我正在计数和拼接槽array_splice函数的数组中保留键。看起来我使用错误的方法来实现我的目标,但我想看看是否有可能array_splice

我有 2 个数组:

  1. 任务
  2. 雇员

任务和员工(缺席)数组:

$task_id = ['998', '997', '996', '995', '995', '995', '995', '995', '995', '995', '995', '995'];

$absent = array(
           [
               'employee' => 'POL',
               'absent_from' => '',
               'absent_to' => ''
           ],
           [
               'employee' => 'FAR',
               'absent_from' => '2021-07-12',
               'absent_to' => '2021-07-16'
           ],
           [
               'employee' => 'FARs',
               'absent_from' => '2021-07-12',
               'absent_to' => '2021-07-16'
           ],
           [
               'employee' => 'FARss',
               'absent_from' => '2021-07-12',
               'absent_to' => '2021-07-16'
           ],
           [
               'employee' => 'FARsss',
               'absent_from' => '2021-07-12',
               'absent_to' => '2021-07-16'
           ],
       );

我想要实现的目标: 我想代表task_id所有人employees。因此,例如,我有 10 个任务和 10 名员工,我想将任务划分为 10 个并将它们委派给员工。如果我有 9 个任务和 10 个员工,那么每个人都会得到 2 个任务,但其中一个只会得到 1 个任务。

首先,我从数组中添加另一个数组中的名称$absent

       $absent_name = array();
       foreach($absent as $key => $name) {
           $absent_name[$key] = $name['employee'];
       }

然后我尝试task_id在员工之间拼接(计算员工人数):

        $output = array();                     // Output / Result (Array)
        $input = $task_id;                     // Tasks (ids)
        $num_employees = count($absent_name);  // number of employees
        for (;$num_employees > 0; $num_employees -= 1) {
            $output[] = array_splice($input, 0, ceil(count($input) / $num_employees));
        }
        print_r($output);

结果是这样的:(我已经用更多/更少的员工和task_id进行了测试,看起来结果数组就像我想要的那样划分,但我想保留名称而不是键):

Array
(
    [0] => Array
        (
            [0] => 998
            [1] => 997
            [2] => 996
        )
    [1] => Array
        (
            [0] => 995
            [1] => 995
            [2] => 995
        )    
    [2] => Array
        (
            [0] => 995
            [1] => 995
        )  
    [3] => Array
        (
            [0] => 995
            [1] => 995
        )   
    [4] => Array
        (
            [0] => 995
            [1] => 995
        )
)

我需要的:

Array
(
    [POL] => Array
        (
            [0] => 998
            [1] => 997
            [2] => 996
        )
    [FAR] => Array
        (
            [0] => 995
            [1] => 995
            [2] => 995
        )    
    [FARs] => Array
        (
            [0] => 995
            [1] => 995
        )  
    [FARss] => Array
        (
            [0] => 995
            [1] => 995
        )   
    [FARsss] => Array
        (
            [0] => 995
            [1] => 995
        )
)

或者一些简单的东西,这样我就可以轻松地将它添加到数据库中:

Array
(
    [POL] => [998,997,996]
        )
    [FAR] => [995,995,995]
        )    
    etc......
)

知道我是否需要更改方法或可以使用array_splice吗?

标签: phplaravel

解决方案


我不认为 array_splice 会在这里为您提供任何帮助,IMO 您正在努力工作,应该让 PHP 的数组函数为您完成大部分工作。然后,您可以专注于您的业务逻辑,这非常简单。

使用array_column从 $absent 数组中轻松提取员工 ID。

使用array_map创建和初始化数组的关联数组,以员工 ID 为键。

循环遍历任务 ID 并使用keynextreset函数在分配映射中前进并根据需要环绕。

// Create an associative array keyed by the employee IDs
$employeeTaskMap = array_flip(array_column($absent, 'employee'));

// Initialize the values to empty arrays
$employeeTaskMap = array_map(fn() => [], $employeeTaskMap);

// Loop through the task IDs
foreach ($task_id as $currTaskId)
{
    // Add the task ID to the array at the current pointer in the $employeeTaskMap
    $employeeTaskMap[key($employeeTaskMap)][] = $currTaskId;

    // Advance the array pointer, reset when we reach the end so we can wrap around
    if (next($employeeTaskMap) === false)
    {
        reset($employeeTaskMap);
    }
}

print_r($employeeTaskMap);

输出:

Array
(
    [POL] => Array
        (
            [0] => 998
            [1] => 995
            [2] => 995
        )

    [FAR] => Array
        (
            [0] => 997
            [1] => 995
            [2] => 995
        )

    [FARs] => Array
        (
            [0] => 996
            [1] => 995
        )

    [FARss] => Array
        (
            [0] => 995
            [1] => 995
        )

    [FARsss] => Array
        (
            [0] => 995
            [1] => 995
        )

)

如果您出于某种原因确实想在此处使用 array_splice 并使现有代码正常工作,请在最后使用array_combine以使用员工姓名数组的值作为输出的键:

$taskBuffer    = array();              // Output / Result (Array)
$input         = $task_id;             // Tasks (ids)
$num_employees = count($absent_name);  // number of employees
for (; $num_employees > 0; $num_employees -= 1)
{
    $taskBuffer[] = array_splice($input, 0, ceil(count($input) / $num_employees));
}

$output = array_combine($absent_name, $taskBuffer);

这可行,但是如果您使用更简单、更具声明性的方法,则必须实现许多不必要的低级逻辑。这会在您的代码中引入更多错误的可能性,并使可能使用您的代码的开发人员(包括六个月后的您)难以一目了然地了解您在做什么。


推荐阅读