user22249320
user22249320

Reputation:

Group array values based on array key suffix

I am trying to group my array values based on the array keys then print the result in the UI. I am stuck here for hours now.

Here is the array I need to format:

Array
(
    [checklist1] => major
    [result_audit1] => 1
    [checklist2] => minor
    [result_audit2] => 2
    [checklist3] => pico
    [result_audit3] => 3
    [checklist4] => goodpoints
    [result_audit4] => 4
    [submit] => Submit Now
)

Here is what I have tried so far but it is misaligned and not a proper result of the array.

foreach($n_data as $key => $data)
    {
        $array['checklist'][$i] = array(
            'selected' => $n_data[$key],
            'result_audit' => $n_data[$key]
        );

        $i++;
    }

Desired array:

Array
(
    [checklist] => Array
        (
            [0] => Array
                (
                    [selected] => major
                    [result_audit] => 1
                    [origin] => checklist1
                )

            [1] => Array
                (
                    [selected] => minor
                    [result_audit] => 2
                    [origin] => checklist2
                )
))

Upvotes: 1

Views: 173

Answers (6)

mickmackusa
mickmackusa

Reputation: 48031

Parse the digital suffix of each checklist key and isolate the integer as a temporary value. As you iterate, if you encounter checklist data, push a new subarray into the result array which includes the related result_audit value.

Code: (Demo)

$result = [];
foreach ($array as $k => $v) {
    if (sscanf($k, 'checklist%d', $integer)) {  // isolate integer only on "checklist" keyed elements
        $result['checklist'][] = [
            'selected' => $v,
            'result_audit' => $array["result_audit$integer"],
            'origin' => $k
        ];
    }
}
var_export($result);

If the elegance of this answer isn't immediately obvious, it makes only one function call per iteration and doesn't need to use a regular expression to parse the keys.

Upvotes: 0

lukas.j
lukas.j

Reputation: 7172

$data = [
  'checklist1'    => 'major',
  'result_audit1' => 1,
  'checklist2'    => 'minor',
  'result_audit2' => 2,
  'checklist3'    => 'pico',
  'result_audit3' => 3,
  'checklist4'    => 'goodpoints',
  'result_audit4' => 4,
  'submit'        => 'Submit Now'
];

// Extract array entries where the key starts with 'checklist'
$checklists = array_filter(
  $data,
  fn($key) => str_starts_with($key, 'checklist'),
  ARRAY_FILTER_USE_KEY
);

// ... and loop over these entries
$result = array_map(
  function ($value, $key) use ($data) {
    preg_match('/(\d+)$/', $key, $match);   // Get the number at the end of the key
    return [
      'selected'     => $value,
      'result_audit' => $data['result_audit' . $match[1]],   // Get the 'result_audit...' value from $data
      'origin'       => $key,
    ];
  },
  $checklists,
  array_keys($checklists)
);

print_r($result);

Output:

Array
(
    [0] => Array
        (
            [selected] => major
            [result_audit] => 1
            [origin] => checklist1
        )

    [1] => Array
        (
            [selected] => minor
            [result_audit] => 2
            [origin] => checklist2
        )

    [2] => Array
        (
            [selected] => pico
            [result_audit] => 3
            [origin] => checklist3
        )

    [3] => Array
        (
            [selected] => goodpoints
            [result_audit] => 4
            [origin] => checklist4
        )

)

Upvotes: 1

mousetail
mousetail

Reputation: 8010

You can try something like this:

$n_data= [
    "checklist1" => "major",
    "result_audit1" => "1",
    "checklist2" => "minor",
    "result_audit2" => "2",
    "checklist3" => "pico",
    "result_audit3" => "3",
    "checklist4" => "goodpoints",
    "result_audit4" => "4",
    "submit" => "Submit Now",
];

$array = [];

foreach($n_data as $key => $data)
    {
        // extract the number after the key
        if (str_starts_with($key, "checklist")) {
            $array['checklist'][substr($key, strlen("checklist"))]["selected"] = $data;
            $array['checklist'][substr($key, strlen("checklist"))]["origin"] = $key;
        }
        elseif (str_starts_with($key, "result_audit")) {
            $array['checklist'][substr($key, strlen("result_audit"))]["result_audit"] = $data;
        } else { throw new Exception("Unexpected array key") }
    }

print_r($array);

Demo

Upvotes: 1

nice_dev
nice_dev

Reputation: 17825

Looking at the order and the alignment of your array, you can use array_chunk to split the array into chunks of 2 and then use array_walk to add the keys as you desire. Use array_splice to get rid of the submit key. Below is the compact code for the same.

Snippet:

<?php

$chunked['checklist'] = array_chunk(array_splice($n_data, 0, count($n_data) - 1), 2);
array_walk($chunked['checklist'], fn(&$v, $idx) => $v = ['selected' => $v[0], 'result_audit' => $v[1], 'origin' => 'checklist'. ($idx + 1)]);
print_r($chunked);

Live Demo

Upvotes: 1

esQmo_
esQmo_

Reputation: 1709

I tried something that can result what you need

$datas = array(
    'checklist1' => 'major',
    'result_audit1' => 1,
    'checklist2' => 'minor',
    'result_audit2' => 2,
    'checklist3' => 'pico',
    'result_audit3' => 3,
    'checklist4' => 'goodpoints',
    'result_audit4' => 4,
    'submit' => 'Submit Now'
);

$array = array();
$i = 0;
foreach($datas as $key => $data){
    if (strpos($key, "checklist") !== false) {
        $array['checklist'][$i] = array(
            'selected' => $datas[$key],
            'result_audit' => $n_data["result_audit".substr($key, -1)],
            'origin' => $key
        );
        $i++;
    }
}

//Test
var_export($array);

Here I iterate through $datas array and check if the key contains the string "checklist" and add a new entry to $array['checklist'] array with the desired format. The result_audit value is obtened by concatenating the string "result_audit" with the last character of the current key (index number).

Upvotes: 1

Olivier
Olivier

Reputation: 18250

Here is a way to do it:

$data = ['checklist1'=>'major', 'result_audit1'=>1, 'checklist2'=>'minor', 'result_audit2'=>2, 'submit'=>'Submit Now'];

$res = [];
foreach($data as $key=>$val)
{
    if(substr($key, 0, 9)=='checklist')
    {
        $i = substr($key, -1);
        $res['checklist'][] = ['selected'=>$val, 'result_audit'=>$data['result_audit'.$i], 'origin'=>$key];
    }
}

print_r($res);

Output:

Array
(
    [checklist] => Array
        (
            [0] => Array
                (
                    [selected] => major
                    [result_audit] => 1
                    [origin] => checklist1
                )

            [1] => Array
                (
                    [selected] => minor
                    [result_audit] => 2
                    [origin] => checklist2
                )

        )

)

Upvotes: 1

Related Questions