在PHP中翻转二维关联数组

时间:2016-12-01 13:32:04

标签: php algorithm multidimensional-array associative-array

我需要将父母的一系列父母转变成一系列儿童的父母。例如,我有一个这样的数组:

ECS

我想把它变成这个:

#!/bin/bash

# needed for correct glob expansion
shopt -s nullglob

# we check every file following the format $1.extension
max_index=0
for f in $1.*
do
    # we retrieve the last extension
    ext=${f##*.}
    re="^[0-9]+$"

    # if ext is a number and greater than our max, we store it
    if [[ $ext =~ $re && $ext -gt $max_index ]]
    then
        max_index=$ext
    fi
done
echo $max_index

有没有办法在不使用嵌套的foreach循环的情况下完成此任务?如果没有,最有效的方法是什么?

提前致谢!

3 个答案:

答案 0 :(得分:6)

使用array_merge_recursivearray_combinearray_fill函数的简短解决方案:

$arr = [
    1 => ['a','b','c'],
    2 => ['b','c','d'],
    3 => ['c','d','e'],
];

$result = [];
foreach ($arr as $k => $v) {
    $result = array_merge_recursive($result, array_combine($v, array_fill(0, count($v), [$k])));
}

print_r($result);

输出:

Array
(
    [a] => Array
        (
            [0] => 1
        )

    [b] => Array
        (
            [0] => 1
            [1] => 2
        )

    [c] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [d] => Array
        (
            [0] => 2
            [1] => 3
        )

    [e] => Array
        (
            [0] => 3
        )
)

答案 1 :(得分:2)

在"效率"我相信在这种情况下,嵌套循环更好:

from __future__ import print_function

def split_message(message, character_limit=2000):
    messages = []

    while len(message) > character_limit:
        split_index = message[:character_limit].rfind(" ")
        if split_index == -1:
            # No space found, just split at the character limit
            split_index = character_limit
        else:
            # Else space is found, split after the space
            split_index += 1
        messages.append(message[:split_index])
        message = message[split_index:] 
    messages.append(message)
    return messages

# Test code 
test_string = "this  is a test string to see if this works right"
test_string = "thisisateststringwithnospaces"

for character_limit in range(1, 10):
    print ("limit", character_limit, ": ", split_message(test_string, character_limit))

尝试使用array_map等其他功能获得创意可能会变得更慢,至少根据this answer。可能值得运行一些自己的基准测试。

答案 2 :(得分:0)

使用闭包和array_map(人们只能希望array_map的执行速度比等效的for循环更快......不应该是原生函数吗?)。

$multimap=[
    1 => [a,b,c],
    2 => [b,c,d],
    3 => [c,d,e],
];

$result=[];
foreach($multimap as $k=>$arr) {
  $callme=function($e) use (&$result, $k) {
    if( ! array_key_exists ($e, $result) ) {
      $result[$e]=[];
    }
    $result[$e][]=$k;
    return $e; // not that it matters what is returned, we're after the side-effects
  };
  array_map($callme, $arr);
}

// just as yet another alternative to var_dump/print_r
echo json_encode($result /*, JSON_PRETTY_PRINT */)."\n";