2

我有3个这样的数组:

$a = array(
 0 => 'a1',
 1 => 'a2',
 2 => 'a3'
);

$b = array(
 0 => 'b1',
 1 => 'b2',
 2 => 'b3'
);

$c = array(
 0 => 'c1',
 1 => 'c2',
 2 => 'c3'
);

我喜欢这样的东西:

$r = array(
 0 => 'a1',
 1 => 'b1',
 2 => 'c1',
 3 => 'a2',
 4 => 'b2',
 5 => 'c2',
 6 => 'a3',
 ....
 ...
);

我怎样才能做到这一点并享受使用超过 3 个输入数组的能力?

编辑:

我试过这个:

$a = array(
        0 => 'a1',
        1 => 'a2',
        2 => 'a3',
        3 => 'a4'
    );
    $b = array(
        0 => 'b1',
        1 => 'b2',
        2 => 'b3'
    );
    $c = array(
        0 => 'c1',
        1 => 'c2',
        2 => 'c3',
        3 => 'c4',
        4 => 'c5',
        5 => 'c6'

    );

    $l['a'] = count($a);
    $l['b'] = count($b);
    $l['c'] = count($c);

    arsort($l);
    $largest = key($l);
    $result = array();
    foreach ($$largest as $key => $value) {
        $result[] = $a[$key];
        if(array_key_exists($key, $b)) $result[] = $b[$key];
        if(array_key_exists($key, $c)) $result[] = $c[$key];

    }
    print_r($result);

输出:Array ( [0] => a1 [1] => b1 [2] => c1 [3] => a2 [4] => b2 [5] => c2 [6] => a3 [7] => b3 [8] => c3 [9] => a4 [10] => c4 [11] => [12] => c5 [13] => [14] => c6 )

这可行,但代码不好。有没有人有更好的解决方案?

解决方案: 我用一些动态功能更新了@salathe 的帖子

function comb(){
    $arrays = func_get_args();
    $result = array();
    foreach (call_user_func_array(array_map, $arrays) as $column) {
        $values = array_filter($column, function ($a) { return $a !== null; });
        $result = array_merge($result, $values);
    }
    return $result;
}
print_r(comb(null,$a,$b,$c,$d,....));
4

9 回答 9

1

您可以使用该array_map()功能来完成大部分艰苦的工作。

在示例中,循环内的代码仅从每个数组中获取值(null如果没有对应的值),如果有值,则将它们附加到$results数组中。

例子

$result = array();
foreach (array_map(null, $a, $b, $c) as $column) {                                          
    $values = array_filter($column, function ($a) { return $a !== null; });
    $result = array_merge($result, $values);
}
var_export($result);

输出

array (
  0 => 'a1',
  1 => 'b1',
  2 => 'c1',
  3 => 'a2',
  4 => 'b2',
  5 => 'c2',
  6 => 'a3',
  7 => 'b3',
  8 => 'c3',
  9 => 'a4',
  10 => 'c3',
  11 => 'c3',
  12 => 'c3',
)
于 2013-10-20T15:54:55.583 回答
1

对不起我之前的回答,误读了这个问题。这就是你需要的:

$arrays = array($a,$b,$c);

$new = array();

$count = count($arrays);
while(count($arrays) > 0) {

    for($i = 0; $i < $count; $i++) {
        if (isset($arrays[$i])) {
        array_push($new, array_shift($arrays[$i]));
        if (count($arrays[$i]) == 0) {
            unset($arrays[$i]);
            }
        }
    }
}

即使对于大小不相等的数组:

$a = array(
 0 => 'a1',
 1 => 'a2',
 2 => 'a3',
 3 => 'a4'
);

$b = array(
 0 => 'b1',
 1 => 'b2',
 2 => 'b3'
);

$c = array(
 0 => 'c1',
 1 => 'c2',
 2 => 'c3',
 3 => 'c4'
);

你会得到结果:

Array
(
    [0] => a1
    [1] => b1
    [2] => c1
    [3] => a2
    [4] => b2
    [5] => c2
    [6] => a3
    [7] => b3
    [8] => c3
    [9] => a4
    [10] => c4
)
于 2013-10-20T16:11:30.157 回答
1

需要一些编码:

function customMerge()
{
    $arrays = func_get_args();
    $res = array();
    $continue = true;
    while($continue){
       $continue = false;
       for($j=0;$j<count($arrays); $j++){
          if($pair = each($arrays[$j]){
              if(is_numeric($pair[0])
                  $res[] = $pair[1];
              else
                  $res[ $pair[0] ] = $pair[1];
              $continue = true;
          }
       }
    }
    return $res;
}  

$res = customMerge($arr1, $arr2, $arr3, ...);
于 2013-10-20T15:33:42.270 回答
0

假设count($a)=count($b)=count($c),这可以通过以下方式完成:

<?php
   $var = array();
   for($i=0;$i<count($a);$i++)
   {
    array_push($var,$a[$i]);
    array_push($var,$b[$i]);
    array_push($var,$c[$i]);
    }
  print_r($var);
 ?>

这将导致:

Array ( [0] => a1 [1] => b1 [2] => c1 [3] => a2 [4] => b2 [5] => c2 [6] => a3 [7] => b3 [8] => c3 )

编辑:对于@eggyal
,我试过了:

<?php
 $a = array(
    0 => 'a1',
    1 => 'a2',
    2 => 'a3',
    3 => 'a4'
);
$b = array(
    'x' => 'b1',
    'y' => 'b4',
    'z' => 'b3'
);
$c = array(
    0 => 'c1',
    'p' => 'c2',
    2 => 'c3',
    3 => 'c3',
    'q' => 'c3',
    5 => 'c3'

);
$d = array_merge($b,$a,$c);//place arrays in any order like $a,$b,$c or $b,$a,$c or $c,$b,$a
sort($d);
print_r($d);
?>

这导致:

Array ( [0] => a1 [1] => a2 [2] => a3 [3] => a4 [4] => b1 [5] => b3 [6] => b4 [7] => c1 [8] => c2 [9] => c3 [10] => c3 [11] => c3 [12] => c3 )

我不确定这是否满足你。但是,我认为合并仍然发生。但是,它不保留密钥。

于 2013-10-20T15:19:50.517 回答
0

你可以这样做:

function getMaxLength(array $arrays) {
    $len = count($arrays);

    if($len == 0) {
        return 0;
    }

    $max = count($arrays[0]);
    for($i = 1; $i < $len; $i++) {
        $count = count($arrays[$i]);
        if($count > $max) {
            $max = $count;
        }
    }

    return $max;
}

function combine() {
    $arrays = func_get_args();
    $maxLength = getMaxLength($arrays);
    $combined = array();
    for($i = 0; $i < $maxLength; $i++) {
        foreach($arrays as $array) {
            if(isset($array[$i])) {
                $combined[] = $array[$i];
            }
        }
    }
    return $combined;
}

print_r(combine($a, $b, $c));
于 2013-10-20T15:36:46.143 回答
0

可以通过排序完成

$arr = array_merge($a,$b,$c);

foreach ($arr as $key => $val) {
  $numsort[$key] = substr($val,1);
  $charsort[$key] = substr($val,0,1);
}

array_multisort($arr, SORT_ASC, SORT_NUMERIC, $numsort, $arr, SORT_ASC, $charsort);

// result

Array
(
    [0] => a1
    [1] => b1
    [2] => c1
    [3] => a2
    [4] => b2
    [5] => c2
    [6] => a3
    [7] => b3
    [8] => c3
)
于 2013-10-20T16:37:09.117 回答
0

您的案例只是与一些特定的顺序合并。这样做的明确方法是:

  1. 合并数组
  2. 排序结果

代码示例:

$merged = array_merge($a, $b, $c);
usort($merged, function($left, $right) {
        if (substr($left, 1) == substr($right, 1)) {//if numbers equal check letters
                return (substr($left, 0, 1) < substr($right, 0, 1)) ? -1 : 1;
        }
        return (substr($left, 1) < substr($right, 1)) ? -1 : 1;
});

print_r($merged);

输出:

Array
(
    [0] => a1
    [1] => b1
    [2] => c1
    [3] => a2
    [4] => b2
    [5] => c2
    [6] => a3
    [7] => b3
    [8] => c3
)

有更通用的解决方案(所有第一行都是后续的,所有第二行都是后续的......):

$result = call_user_func_array('array_merge', array_map(
        function () {
                return array_filter(func_get_args(), function ($element) {
                                return $element !== null;
                });
        } , $a, $b, $c)
);

print_r($结果);

于 2013-10-20T16:06:34.987 回答
0

这个逻辑很烂..虽然有效

<?php

$a = array(
    0 => 'a1',
    1 => 'a2',
    2 => 'a3'
);

$b = array(
    0 => 'b1',
    1 => 'b2',
    2 => 'b3'
);

$c = array(
    0 => 'c1',
    1 => 'c2',
    2 => 'c3',
    3 => 'c4',
    4 => 'c5' 
);

$val=5; //Size of the largest array  (largest array is c)

$d=array();
for($i=0;$i<$val;$i++)
{
    $d[]=$a[$i];
    $d[]=$b[$i];
    $d[]=$c[$i];
}

//Clearing empty values
foreach ($d as $key=>$value)
if (empty($value))
    unset($d[$key]);



 //Consecutive Keys 
       $finalArray = array_values($d);
       print_r($finalArray);

输出 :

Array ( [0] => a1 [1] => b1 [2] => c1 [3] => a2 [4] => b2 [5] => c2 [6] => a3 [7] => b3 [8] => c3 [9] => c4 [10] => c5 )
于 2013-10-20T15:10:55.490 回答
0

在找到此页面之前,我回答了一个重复项。我下面...$row的解决方案用于输入数据,但对于这个问题,只需切换...$rows. $a, $b, $c我已经删除了我的其他答案并使用此页面敲定了重复的问题。

我对功能性单线的想法(为了便于阅读,我将其拆分并标记了标签)如下。请注意,早期过滤将意味着最大限度地减少“无用数据”处理,而后期过滤将减少函数调用。

使用贪婪/懒惰/虚假过滤进行后期过滤:(演示

var_export(
    array_filter(          #remove nulls
        array_merge(       #flatten the unpacked elements
            ...array_map(  #unpack
                null,      #transpose
                ...$rows   #transpose
            )              #unpack
        )                  #flatten the unpacked elements    
    )                      #remove nulls
);

简洁的单行语法:( Demo )

var_export(array_filter(array_merge(...array_map(null, ...$rows))));

使用贪婪/懒惰/虚假过滤的中间过滤:(演示

var_export(
    array_merge(              #flatten the unpacked elements
        ...array_filter(      #remove nulls from transposing then unpack
            array_map(        #transpose
                null,         #transpose
                ...$rows      #transpose
            )                 #transpose
        )                     #remove nulls from transposing then unpack
    )                         #flatten the unpacked elements
);

或者做早期过滤......(贪婪/懒惰/虚假过滤)

代码:(演示

var_export(
    array_merge(                     #flatten the unpacked elements
        ...array_map(                #unpack
            function() {             #transpose discarding nulls
                return array_filter( #transpose discarding nulls
                    func_get_args()  #transpose discarding nulls
                );                   #transpose discarding nulls
            },                       #transpose discarding nulls
            ...$rows                 #transpose discarding nulls
        )                            #unpack
    )                                #flatten the unpacked elements
);

或使用贪婪/懒惰/虚假过滤和更多“喷溅”进行早期过滤:(演示

var_export(
    array_merge(                         #flatten the unpacked elements
        ...array_map(                    #unpack
            function(...$v) {            #transpose discarding nulls
                return array_filter($v); #transpose discarding nulls
            },                           #transpose discarding nulls
            ...$rows                     #transpose discarding nulls
        )                                #unpack
    )                                    #flatten the unpacked elements
);

这是PHP7.4版本:(演示

var_export(
    array_merge(                           #flatten the unpacked elements
        ...array_map(                      #unpack
            fn(...$v) => array_filter($v), #transpose discarding nulls
            ...$rows                       #transpose discarding nulls
        )                                  #unpack
    )                                      #flatten the unpacked elements
);

浓缩为:

var_export(array_merge(...array_map(fn(...$v) => array_filter($v), ...$rows)));
于 2020-06-16T07:24:07.743 回答