根据键从动态关联数组中创建二进制成对数组,每个键一个元素

时间:2019-04-20 08:50:19

标签: php arrays multidimensional-array

我基本上是通过一种动态关联数组创建对的,使得我从一个键数组中取了一个元素,并从其他键数组中取了另一个元素,将这两个元素组合成对。这是一个动态关联数组可以有4个具有数组的键,每个键在其数组中最多可以包含两个元素,最少应包含1个元素。要成对,我们应该在这两个键数组的两侧都具有两个包含1个元素的键。 例如

    [parent_id] => Array
            (
                [9] => Array
                    (
                        [0] => 11
                        [1] => 12
                    )

                [10] => Array
                    (
                        [0] => 13
                        [1] => 14
                    )

                [20] => Array
                    (
                        [0] => 21
                        [1] => 22
                    )
                [21] => Array
                    (
                        [0] => 23
                    )

            )

这是一个关联数组,目前提供3对。 例如
对1 包含:11,13
对2 包含:12,14
对3 包含:21,23

现在的问题是,通过使用什么方法我可以获得我想要的结果。 有任何建议!!!!

1 个答案:

答案 0 :(得分:2)

更新3

上一次更新未找到一种情况下所有可能的对。此版本的循环方式不同,从每个数组最多获取一个元素,然后再移至下一个并从那里进行配对。一直循环直到没有足够的值可以配对。

function find_pairs($array) {
    // re-index to 0
    $array = array_values($array['parent_id']);
    // sort so the longest arrays are first
    usort($array, function ($a, $b) { return count($b) - count($a); });
    // output array
    $pairs = array();
    $c = count($array);
    $i = 0;
    // loop while there are enough values to pair (2 or more)
    while (array_reduce($array, function ($c, $v) { return $c + count($v); }, 0) > 1) {
        // make sure there are some elements in this array
        while (!count($array[$i])) $i = ($i + 1) % $c;
        // find the next array with a value
        $j = ($i + 1) % $c;
        while (!count($array[$j])) $j = ($j + 1) % $c;
        // have we come full circle?
        if ($j == $i) break;
        // save the pair
        $pairs[] = array(array_shift($array[$i]), array_shift($array[$j]));
        // move on to the next array
        $i = ($i + 1) % $c;
    }
    return $pairs;
}

Demo (includes all possible test cases) on 3v4l.org

原始答案

这是执行此操作的一种方法。重新索引parent_id数组以使其从0开始,然后一次遍历数组2个元素,合并每个元素的所有值。我们使用min来确保我们只对与最小值数组中的所有值进行配对。

// re-index to 0
$array = array_values($array['parent_id']);
// output array
$pairs = array();
for ($i = 0; $i < count($array) - 1; $i += 2) {
    for ($j = 0; $j < min(count($array[$i]), count($array[$i+1])); $j++) {
        $pairs[] = array($array[$i][$j], $array[$i+1][$j]);
    }
}
print_r($pairs);

输出:

Array (
  [0] => Array ( [0] => 11 [1] => 13 )
  [1] => Array ( [0] => 12 [1] => 14 ) 
  [2] => Array ( [0] => 21 [1] => 23 ) 
)

Demo on 3v4l.org

更新

如果要保证从数组中获得最大对数,请排序以使最长的数组排在最前面:

$array = array_values($array['parent_id']);
// sort so the longest arrays are first
usort($array, function ($a, $b) { return count($b) - count($a); });
// output array
$pairs = array();
for ($i = 0; $i < count($array) - 1; $i += 2) {
    for ($j = 0; $j < min(count($array[$i]), count($array[$i+1])); $j++) {
        $pairs[] = array($array[$i][$j], $array[$i+1][$j]);
    }
}
print_r($pairs);

Demo on 3v4l.org

更新2

根据进一步的评论,似乎唯一的配对要求是,来自其的元素所组成的数组的键不相同。这会使事情变得更加复杂,但是此函数应该可以执行您想要的操作:

function find_pairs($array) {
    // re-index to 0
    $array = array_values($array['parent_id']);
    // sort so the longest arrays are first
    usort($array, function ($a, $b) { return count($b) - count($a); });
    // output array
    $pairs = array();
    for ($i = 0, $j = 1; $i < count($array) - 1; $i++) {
        if (!count($array[$i])) continue;
        while ($j <= $i || $j < count($array) && !count($array[$j])) $j++;
        while (count($array[$i]) && isset($array[$j]) && count($array[$j])) {
            $pairs[] = array(array_shift($array[$i]), array_shift($array[$j]));
            // exhausted other arrays elements?
            while ($j < count($array) && !count($array[$j])) $j++;
        }
    }
    return $pairs;
}

Demo on 3v4l.org