3

大家好,我试图从这个数组中找到重复的 x 值并将它们删除,只留下唯一的值。例如我的数组是

Array
(
[0] => Array
    (
        [x] => 0.5
        [y] => 23
    )

[1] => Array
    (
        [x] => 23
        [y] => 21.75
    )

[2] => Array
    (
        [x] => 14.25
        [y] => 21.875
    )

[3] => Array
    (
        [x] => 19.375
        [y] => 21.75
    )

[4] => Array
    (
        [x] => 9.125
        [y] => 21.875
    )

[5] => Array
    (
        [x] => 23
        [y] => 19.625
    )

[6] => Array
    (
        [x] => 19.375
        [y] => 19.625
    ) 
)

所以我需要做的是循环遍历整个事情,然后将第一个 x 值视为 .5 然后继续,将 x 为 .5 的任何其他内容从数组中删除,以便最后我有一个看起来像这样的数组

 Array
   (
[0] => Array
    (
        [x] => 0.5
        [y] => 23
    )

[1] => Array
    (
        [x] => 23
        [y] => 21.75
    )

[2] => Array
    (
        [x] => 14.25
        [y] => 21.875
    )

[3] => Array
    (
        [x] => 19.375
        [y] => 21.75
    )

[4] => Array
    (
        [x] => 9.125
        [y] => 21.875
    )
)

其中所有 X 值都是唯一的。我在网上搜索并发现可以使用此功能,但这似乎不起作用:

 $result = array_map("unserialize", array_unique(array_map("serialize", $array)));    
4

4 回答 4

5

只需循环并找到独特的值:

$taken = array();

foreach($items as $key => $item) {
    if(!in_array($item['x'], $taken)) {
        $taken[] = $item['x'];
    } else {
        unset($items[$key]);
    }
}

每次第一次使用该x值时,我们都会保存它 - 后续使用unset来自数组。

于 2014-02-24T23:13:17.370 回答
0

array_unique比较字符串值,因此您可以创建对象(使用重载__toString函数)作为中间步骤。

class XKeyObj {
    public $x;
    public $y;

    public function XKeyObj($x, $y) {
        $this->x = $x;
        $this->y = $y;
    }

    public function __toString() { return strval($this->x); }
}

function array_to_xKey($arr) { return new XKeyObj($arr['x'], $arr['y']); }
function xKey_to_array($obj) { return array('x' => $obj->x, 'y' => $obj->y); }

$input = array(
    array('x' => 0.5, 'y' => 23),
    array('x' => 23, 'y' => 21.75),
    array('x' => 14.25, 'y' => 21.875),
    array('x' => 19.375, 'y' => 21.75),
    array('x' => 9.125, 'y' => 21.875),
    array('x' => 23, 'y' => 19.625),
    array('x' => 19.375, 'y' => 19.625)
);

$output = array_map('xKey_to_array',
                    array_unique(array_map('array_to_xKey', $input)));

print_r($output);

结果:

Array
(
    [0] => Array
        (
            [x] => 0.5
            [y] => 23
        )

    [1] => Array
        (
            [x] => 23
            [y] => 21.75
        )

    [2] => Array
        (
            [x] => 14.25
            [y] => 21.875
        )

    [3] => Array
        (
            [x] => 19.375
            [y] => 21.75
        )

    [4] => Array
        (
            [x] => 9.125
            [y] => 21.875
        )

)
于 2014-02-24T23:46:07.053 回答
0

在对数组执行迭代检查时,in_array()随着临时查找数组大小的增加,性能拖累将逐渐恶化。

考虑到这一点,使用临时关联键来识别后续重复项,以便!isset()可以在您不断增长的结果变量上调用。因为 php 数组是哈希映射,所以这种技术将始终优于in_array().

这些临时键有一个陷阱,专门适用于您的浮点类型值。 当浮点数用作数组键时,php 将通过截断(“地板”而不是“舍入”)将它们转换为整数。为了避免这种不必要的副作用,请在临时键前面添加一个非数字字符(当然,连字符除外),以便浮点数变为字符串。

代码:(演示

$array = [
    ['x' => 0.5, 'y' => 23],
    ['x' => 23, 'y' => 21.75],
    ['x' => 14.25, 'y' => 21.875],
    ['x' => 19.375, 'y' => 21.75],
    ['x' => 9.125, 'y' => 21.875], 
    ['x' => 23, 'y' => 19.625],
    ['x' => 19.375, 'y' => 19.625],
];

foreach ($array as $row) {
    if (!isset($result['#' . $row['y']])) {
        $result['#' . $row['y']] = $row;
    }
}
var_export(array_values($result));

从 PHP7.4+ 开始享受空值合并赋值运算符(Demo

foreach ($array as $row) {
    $result['#' . $row['y']] ??= $row;
}
var_export(array_values($result));

输出:

array (
  0 => 
  array (
    'x' => 0.5,
    'y' => 23,
  ),
  1 => 
  array (
    'x' => 23,
    'y' => 21.75,
  ),
  2 => 
  array (
    'x' => 14.25,
    'y' => 21.875,
  ),
  3 => 
  array (
    'x' => 23,
    'y' => 19.625,
  ),
)

ps 如果将字符串或整数值作为临时键处理,则无需添加任何字符。如果您不关心从结果中删除临时键(因为您只访问子数组值“向下脚本”,那么您不需要array_values()在迭代后调用。

于 2019-09-07T21:26:07.450 回答
-2
array_unique(my_array, SORT_REGULAR)
于 2014-02-24T23:14:28.697 回答