0

I've read that it makes no sense to push new key value pairs into arrays. But how could this situation be solved best?

I have a multidim array of tutor and courses data:

$data = [
     ['tutor_name' => 'John Doe', 'course_day' => 'Monday', ...],
     ['tutor_name' => 'John Doe', 'course_day' => 'Tuesday', ...]
     ...
   ];

I need to translate all the days into my language (cz) so I wrote a switch:

function translate_to_cz ($day) {
    switch ($day) {
        case "Monday":
          $day_cz = "Pondělí";
        break;
        case "Tuesday":
          $day_cz = "Úterý";
        break;
    ...
    }
    return $day_cz;
  }

I need a loop that would send $data['course_day'] to the switch. The $day_cz would then be returned to the original array, preferably with a new key $data['course_day_cz'] waiting for it. Can this be done? Thanks

Nick
  • 138,499
  • 22
  • 57
  • 95
  • 1
    You should always tag your question with the coding language, that will ensure it gets seen by the largest possible audience. – Nick Sep 08 '20 at 00:10

2 Answers2

2

how could this situation be solved best?

Well, you seem to want to perform a value replacement, so create a lookup and access the appropriate replacement by its key.

Do not bloat your script with a switch block, just create a lookup array, then replace while iterating your rows of data. You can use an iterating function or a simple foreach() loop.

Code: (Demo) (Modern syntax since PHP7.4)

$enToCz = [
    'Monday' => 'Pondělí',
    'Tuesday' => 'Úterý'
];

$data = [
    ['tutor_name' => 'John Doe', 'course_day' => 'Monday',],
    ['tutor_name' => 'John Doe', 'course_day' => 'Tuesday',]
];

array_walk(
    $data,
    function (&$row) use ($enToCz) {
        $row['course_day_cz'] = $enToCz[$row['course_day']];
    }
);

/* or you can use:
   foreach ($data as &$row) {
       $row['course_day_cz'] = $enToCz[$row['course_day']];
   }
*/

var_export($data);

Output:

array (
  0 => 
  array (
    'tutor_name' => 'John Doe',
    'course_day' => 'Monday',
    'course_day_cz' => 'Pondělí',
  ),
  1 => 
  array (
    'tutor_name' => 'John Doe',
    'course_day' => 'Tuesday',
    'course_day_cz' => 'Úterý',
  ),
)

Explanation of syntax:

  1. & before a variable means "modify by reference" (that is the term to search if you want to do some more research). It allows the data held in the variable to be directly mutated. This is necessary when a "copy of a variable" is being accessed.

    There is some rather informative chatter at PHP foreach change original array values.

  2. use() is a technique used to transfer global variables into the scope of a custom function (closure).

    In PHP, what is a closure and why does it use the "use" identifier?


Also array_map() can be used to return an array with the additional column without needing to declare a result array or modifying the original array. (Demo)

var_export(
    array_map(
        fn($row) => $row + ['course_day_cz' => $enToCz[$row['course_day']]],
        $data
    )
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • Thanks that worked! Never seen the ampersand and the use keyword. What is this concept/syntax called? So that I could study it more. I found the term bitwise operators but it seems to me that that's something else... – Jakub Jenč Sep 08 '20 at 14:40
  • Added explanation – mickmackusa Sep 08 '20 at 20:54
1

You can use a foreach loop over $data, using a reference to the value so you can modify it in the loop and calling the translate function on the course_day value:

foreach ($data as &$value) {
    $value['course_day_cz'] = translate_to_cz($value['course_day']);
}

Demo on 3v4l.org

Nick
  • 138,499
  • 22
  • 57
  • 95