如何从两个数组中删除重复的元素对?

4

I've two arrays like this:

$arr = Array (1, 2, 3 ,4 ,5, 6 ,7 ,8 ) ;

并且这个:

$arr2 = Array (7, 6, 5,8 ,3 ,2 ,1, 4 )  

这些数组中的配对元素是具有相同键值的数字(例如 $arr[0]-$arr2[0] 等)。
1-7
2-6
3-5
4-8
5-3
6-2
7-1
8-4

正如您所看到的,有一些重复的配对,例如1-7和7-1,2-6和6-2,3-5和5-3,4-8和8-4。

我需要一个函数,接收这两个数组并返回一个仅包含单个配对的数组。

例如,此函数应该返回以下结果:

Array ( [0] => 1 [1] => 7 [2] => 2 [3] => 6 [4] => 3 [5] => 5 [6] => 4 [7] => 8 ) 

你可以看到这些配对是:1-7,2-6,3-5和4-8。
我写了一个函数,但它不能正常工作。
function free_pairs($arr,$arr2){
$ok = 0;
$ris = array();
$indice_ris=0;
for ($i=1; $i <=count($arr) ; $i++) { 
    $x1 = $arr[$i];
    $x2 = $arr2[$i];
    for ($j=1; $j <= count($arr2) ; $j++) { 
        $y1 = $arr[$j];
        $y2 = $arr2[$j];
        if($x1 != $y2 && $x2 != $y1){
            $ok = 1;
        } else {
            $ok = 0;
        }
    }
    if ($ok == 1) {
        $ris[$indice_ris] = $x1;
        $ris[$indice_ris+1] = $x2;
        $indice_ris = $indice_ris+2;
        $ok = 0;
    }
    return $ris;
}

我认为问题就在这个 if 语句中:
if($x1 != $y2 && $x2 !=$y1)

你对此有何看法?

5个回答

1
经过对您原始脚本的一些更正,这个似乎可以工作:
$arr1 = Array (1, 2, 3, 4 ,5, 6 ,7 ,8);
$arr2 = Array (7, 6, 5, 8 ,3 ,2 ,1, 4);
$res = free_pairs($arr1, $arr2);
print_r($res);

function free_pairs($arr,$arr2){
    $ris = array();
    for ($i = 0; $i < count($arr); $i++) { 
        $x1 = $arr[$i];
        $x2 = $arr2[$i];
        $ok = 0;
        for ($j = $i+1; $j < count($arr2); $j++) { 
            $y1 = $arr[$j];
            $y2 = $arr2[$j];
            if($x1 == $y2 && $x2 == $y1){
                $ok = 1;
            }
        }
        if ($ok == 0) {
            $ris[] = $x1;
            $ris[] = $x2;
        }
    }
    return $ris;
}

输出:

Array
(
    [0] => 5
    [1] => 3
    [2] => 6
    [3] => 2
    [4] => 7
    [5] => 1
    [6] => 8
    [7] => 4
)

0

我认为最内层的if语句是错误的:

        if($x1 != $y2 && $x2 !=$y1){
            $ok = 1;
        }
        else{
            $ok=0;
        }

$ok 在每次迭代中被覆盖; $ ok 始终具有值,就好像您省略了循环并设置了 $ j = count($ arr2)-1 。这显然不对。

可能还存在其他问题...

我还注意到您的数据结构有些奇怪。 一些事情:

  • 看起来很容易意外地使一个数组偏离一个,从而使每个配对都不匹配。 您可能希望切换到 $ arr [i] [0] 和 $ arr [i] [1] 成为一对。 这样,无法意外对配对进行错误的匹配。
  • 如果在您的配对中顺序不重要,则保持
  • 根据您的性能要求,并给定p₀≤p₁不变量,您可以将每个配对只存储为字符串"p₀,p₁"。 然后,标准(甚至内置的)sort和unique函数将毫不费力地工作。

0

另一种方式:

$arr1 = array(1, 2, 3, 4, 5, 6, 7, 8);
$arr2 = array(7, 6, 5, 8, 3, 2, 1, 4);

function concat(&$item, $key, $arr)
{
    $item2 = $arr[$key];
    if($item < $item2)
        $item .= "-" . $item2;
    else
        $item = $item2 . "-" . $item;
}

array_walk($arr1, 'concat', $arr2);
print_r($arr1);

$arr = array_unique($arr1);
print_r($arr);

0

试试这个:

$arr1 = array (1, 2, 3 ,4 ,5, 6 ,7 ,8 ) ;
$arr2 = array (7, 6, 5,8 ,3 ,2 ,1, 4 ) ; 

$arr3 = array();

$pairs = array();

for($i =0;$i<count($arr1);$i++)
{
    $pair1 = $arr1[$i].'-'.$arr2[$i];
    $pair2 = $arr2[$i].'-'.$arr1[$i];

    if(!isset($pairs[$pair1]) && !isset($pairs[$pair2]))
    {
        $arr3[] = $arr1[$i];
        $arr3[] = $arr2[$i];

        $pairs[$pair1] = true;
    }
}

$arr3 是你的最终数组。


0

面向对象的方法:

class Pair {
    private $x;
    private $y;

    public function __construct($a, $b) {
        $this->x = ($a > $b ? $a : $b);
        $this->y = ($a > $b ? $b : $a);
    }

    public function __toString() {
        return "{$this->x}, {$this->y}";
    }

    public static function uniquePairs($arr1, $arr2) {
        $pairs = array();
        foreach(array_combine($arr1, $arr2) as $key => $val) {
            $pair = new Pair($key, $val);
            $pairs[(string)$pair] = $pair;
        }
        return $pairs;
    }
}

// usage:
var_dump(Pair::uniquePairs(array(1,2,3,4,5,6,7,8), array(7,6,5,8,3,2,1,4)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接