简体   繁体   English

PHP过滤数组值,并从多维数组中删除重复项

[英]php filter array values and remove duplicates from multi dimensional array

Hello all im trying to find duplicate x values from this array and remove them and only leave the unique ones. 大家好,我试图从该数组中查找重复的x值并将其删除,只保留唯一的x值。 For example my array is 例如我的数组是

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
    ) 
)

So what i need to happen is loops through the entire thing and see the first x value as .5 then continue and whatever else has x as .5 remove it from the array so that at the end i have a array that looks like this 所以我需要做的是遍历整个事物,将第一个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
    )
)

where all the X values are unique. 其中所有X值都是唯一的。 I searched online and found this function to use but this doesnt seem to work: 我在线搜索,发现要使用此功能,但这似乎不起作用:

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

Just loop through and find unique values as you go: 只要遍历并查找唯一的值即可:

$taken = array();

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

Each the first time the x value is used, we save it - and subsequent usages are unset from the array. 每次第一次使用x值时,我们都会保存它-数组中未unset后续用法。

array_unique compares string values, so you can create objects (with an overloaded __toString function) as an intermediate step. 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);

The 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] => 19.375
            [y] => 21.75
        )

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

)

When performing iterated checks on arrays, the performance drag with in_array() will progressively worsen as your temporary lookup array increases in size. 对数组执行迭代检查时,随着临时查找数组大小的增加,使用in_array()的性能拖累将逐渐恶化。

With this in mind, use temporary associative keys to identify subsequent duplicates so that !isset() can be called on your growing result variable. 考虑到这一点,请使用临时关联键来标识后续重复项,以便可以在不断增长的结果变量上调用!isset() Because php arrays are hash maps, this technique will consistently outperform in_array() . 由于php数组是哈希映射,因此此技术将始终优于in_array()

There IS a gotcha with these temporary keys which applies specifically to your float type values. 这些临时键有一个陷阱,它们专门适用于您的浮点类型值。 When floats are used as array keys, php will convert them to integers by truncating ("flooring" not "rounding"). 当将float用作数组键时,php将通过截断将它们转换为整数(“ flooring”而非“ rounding”)。 To avoid this unwanted side-effect, prepend a non-numeric character (other than a hyphen, of course) to the temporary keys so that the float becomes a string. 为避免这种不必要的副作用,请在临时键之前加上一个非数字字符(当然不是连字符),以便浮点数成为字符串。

Code: ( Demo ) 代码:( 演示

$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));

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' => 23,
    'y' => 19.625,
  ),
)

ps If dealing with string or integer values as temporay keys there is no need to prepend any characters. ps如果将字符串或整数值作为速度键处理,则不需要任何字符。 If you don't care about removing the temporary keys from the result (because you are only accessing the subarray values "down script", then you don't need to call array_values() after iterating. 如果您不关心从结果中删除临时键(因为只访问子数组值“向下脚本”,则不需要在迭代后调用array_values()

array_unique(my_array, SORT_REGULAR)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM