Jump to content
NotionCommotion

Changing array keys using another array

Recommended Posts

I have a sequential multidimensional array with many outer rows where all the inner arrays have the same number of elements as another sequential array which represents metadata of the first array's inner arrrays.

$keys: 

["time","system1_typeA","system2_typeA","system1_typeB","system3_typeC","system2_typeB","system1_typeC"]

$arrayValues: 

[
    ["2020-06-27 07:40:06",2.16,9.25,9.44,7.76,5.43,1.12],
    ["2020-06-27 07:40:23",2.66,8.93,4.31,6.59,8.44,3.42],
    ["2020-06-27 07:41:24",8.71,2.78,8.92,6.58,3.65,4.38],
    ["2020-06-27 07:41:58",1.86,6.36,2.65,3.99,7.25,3.32],
    ["2020-06-27 07:42:33",8.71,3.66,8.82,8.54,8.22,4.51]
]


My desired output is: 

{
    "time": ["2020-06-27 07:40:06", "2020-06-27 07:40:23", "2020-06-27 07:41:24", "2020-06-27 07:41:58", "2020-06-27 07:42:33"],
    "system1": {
        "typeA": [2.16, 2.66, 8.71, 1.86, 8.71],
        "typeB": [9.44, 4.31, 8.92, 2.65, 8.82],
        "typeC": [1.12, 3.42, 4.38, 3.32, 4.51]
    },
    "system2": {
        "typeA": [9.25, 8.93, 2.78, 6.36, 3.66],
        "typeB": [5.43, 8.44, 3.65, 7.25, 8.22]
    },
    "system3": {
        "typeC": [7.76, 6.59, 6.58, 3.99, 8.54]
    }
}

Is there much faster way to do so than the following?  I would like to use a built in function like array_combine() if possible, but grouping by system and type creates an issue.

function transform(array $keys, array $arrayValues):array {
    $map=[];
    foreach ($keys as $key) {
        $map[] = explode('_',$key);
    }
    $count=count($keys);

    $newValues=[];
    foreach ($arrayValues as $i=>$arrayValue) {
        $newValues['time'][]=$arrayValue[0];
        for ($i = 1; $i < $count; $i++) {
            $newValues[$map[$i][0]][$map[$i][1]][]=$arrayValue[$i];
        }
    }
    return $newValues;
}

 

Share this post


Link to post
Share on other sites

Want a hint? It's a pretty big one.

array_fill_keys + array_map with array_combine + array_merge_recursive

One-liner.

Share this post


Link to post
Share on other sites
2 hours ago, requinix said:

Want a hint? It's a pretty big one.

array_fill_keys + array_map with array_combine + array_merge_recursive

One-liner.

Is array_map fed the keys and not the arrayValues?

$map = array_map(function($v) {
    return explode('_',$v);
    }, $keys);


Is array_fill_keys being passed an array for the second argument?

Maybe another small (or big) hint?

Share this post


Link to post
Share on other sites

Hint #2: I gave you the function calls in order, so array_fill_keys to get one array, array_map with a simple callback that uses array_combine, and finally array_merge_recursive with both results.

Hint #3a: array_fill_keys starts off your output array with no data, array_map processes your data array, array_combine does the most logical thing it can do under those circumstances.
Hint #3b: If array_merge_recursive tries to merge an array and a string, it'll add the string into the array.

Share this post


Link to post
Share on other sites

Not a one-liner, but still shorter

foreach ($keys as  $i => $k)  {
    @list($k1, $k2) = explode('_', $k);
    if ($k2) 
        $$k1[$k2] = array_column($arrayValues, $i);
    else
        $$k1 = array_column($arrayValues, $i);
}

 

Share this post


Link to post
Share on other sites
16 hours ago, requinix said:

Hint #2: I gave you the function calls in order, so array_fill_keys to get one array, array_map with a simple callback that uses array_combine, and finally array_merge_recursive with both results.

Hint #3a: array_fill_keys starts off your output array with no data, array_map processes your data array, array_combine does the most logical thing it can do under those circumstances.
Hint #3b: If array_merge_recursive tries to merge an array and a string, it'll add the string into the array.

Are you assuming starting with the $keys and $arrayValues in my original post?
 

    $arr1 = array_fill_keys($keys, []);
    echo(json_encode($arr1).PHP_EOL);
    $arr2 = array_fill_keys($keys, $arrayValues);
    echo(json_encode($arr2).PHP_EOL);

    $values = array_map(function($values) use($keys, $arr1, $arr2) {
        //$arr=array_combine($arr1, $values);   //Array to string conversion
        //$arr=array_combine($arr2, $values);   //Array to string conversion
        $arr=array_combine($keys, $values);
        return $arr;
        }, $arrayValues);

    echo(json_encode($values).PHP_EOL);
{
    "time": [],
    "system1_typeA": [],
    "system2_typeA": [],
    "system1_typeB": [],
    "system3_typeC": [],
    "system2_typeB": [],
    "system1_typeC": []
}

{
    "time": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]],
    "system1_typeA": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]],
    "system2_typeA": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]],
    "system1_typeB": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]],
    "system3_typeC": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]],
    "system2_typeB": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]],
    "system1_typeC": [["2020-06-28 08:46:34", 1.71, 6.29, 6.32, 5.55, 1.25, 8.81], ["2020-06-28 08:47:45", 1.88, 8.57, 8.62, 9.98, 8.33, 8.89], ["2020-06-28 08:48:10", 5.75, 4.36, 3.54, 7.93, 8.13, 1.43], ["2020-06-28 08:49:15", 7.14, 9.54, 5.39, 4.58, 5.77, 4.72], ["2020-06-28 08:50:00", 9.42, 7.44, 1.47, 1.87, 1.23, 4.79]]
}
[{
        "time": "2020-06-28 08:46:34",
        "system1_typeA": 1.71,
        "system2_typeA": 6.29,
        "system1_typeB": 6.32,
        "system3_typeC": 5.55,
        "system2_typeB": 1.25,
        "system1_typeC": 8.81
    }, {
        "time": "2020-06-28 08:47:45",
        "system1_typeA": 1.88,
        "system2_typeA": 8.57,
        "system1_typeB": 8.62,
        "system3_typeC": 9.98,
        "system2_typeB": 8.33,
        "system1_typeC": 8.89
    }, {
        "time": "2020-06-28 08:48:10",
        "system1_typeA": 5.75,
        "system2_typeA": 4.36,
        "system1_typeB": 3.54,
        "system3_typeC": 7.93,
        "system2_typeB": 8.13,
        "system1_typeC": 1.43
    }, {
        "time": "2020-06-28 08:49:15",
        "system1_typeA": 7.14,
        "system2_typeA": 9.54,
        "system1_typeB": 5.39,
        "system3_typeC": 4.58,
        "system2_typeB": 5.77,
        "system1_typeC": 4.72
    }, {
        "time": "2020-06-28 08:50:00",
        "system1_typeA": 9.42,
        "system2_typeA": 7.44,
        "system1_typeB": 1.47,
        "system3_typeC": 1.87,
        "system2_typeB": 1.23,
        "system1_typeC": 4.79
    }
]

 

Share this post


Link to post
Share on other sites

Hmm. Apparently I misread the desired output and totally didn't see the whole "split by underscore" bit. That adds a little more difficulty than I had accounted for.

The one-liner was

array_merge_recursive(
	array_fill_keys($keys, []), // initialize to key => []
	...array_map( // flatten outer values array
		$values => array_combine($keys, $values), // inner values arrays get keyed
		$arrayValues
	)
)

Dealing with the keys too will be getting more complicated than I would like to see in a single statement.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.