多维数组,删除键和值与另一个数组匹配的数组。

6
我想删除重复的条目,其中测量值或备用单位与另一个数组匹配,但忽略它们为空的情况。
Array
(
    [0] => Array
        (
            [id] => 2
            [altunit] => %
            [measurement] => 
        )

    [1] => Array
        (
            [id] => 3
            [altunit] => 
            [measurement] => 6
        )

    [2] => Array
        (
            [id] => 4
            [altunit] => %
            [measurement] => 
        )

    [3] => Array
        (
            [id] => 5
            [altunit] => 
            [measurement] => 6
        )

    [4] => Array
        (
            [id] => 6
            [altunit] => 
            [measurement] => 6
        )

)

成为
Array
(
    [0] => Array
        (
            [id] => 2
            [altunit] => %
            [measurement] => 
        )

    [1] => Array
        (
            [id] => 3
            [altunit] => 
            [measurement] => 6
        )

)

我能提供的最好翻译是:“我能想到的最好翻译是:”
$test = array ( 0 => array ( 'id' => '2', 'altunit' => '%', 'measurement' => NULL, ), 1 => array ( 'id' => '3', 'altunit' => NULL, 'measurement' => '6', ), 2 => array ( 'id' => '4', 'altunit' => NULL, 'measurement' => '6', ), 3 => array ( 'id' => '5', 'altunit' => NULL, 'measurement' => '6', ), 4 => array ( 'id' => '6', 'altunit' => NULL, 'measurement' => '6', ), );

$num = [];
foreach($test as $k => $v) $num[] = $v['measurement'];

但是这仅适用于度量,会删除id和altunit键。
6个回答

3
创建一个“已知值”的数组,用于存储测量和替代单位,然后检查它是否存在于其余的值中。
类似下面这样的内容:
$knowed_altunit=array();
$knowed_measurement=array();

foreach($test as $k=>$v){
  if(in_array($v['altunit'],$knowed_altunit) 
  || in_array($v['mesurement'],$knowed_measurement)){
    //if the value of altunit or measurement is already knowed then remove the entry from the array,
    unset($test[$k]);
  }else{
   //if it never been seen, add it so further entry can be checked agaisnt the knowed value
   $knowed_altunit[]=$v['altunit'];
   $knowed_measurement[]=$v['mesurement'];
  }
}

如果有任何错别字,但这可能有助于您理解解决问题的解决方案。


2
你可以尝试这个代码:
<?php

    /* before you need to check that $test variable is declarated and have all items to check */
    $values_altunit = array();
    $values_measurement = array();
    $result = array();

    foreach($test as $key => $value) {
        /* check if exist altunit and measurement values in blacklist arrays */
        if (!in_array($value['altunit'], $values_altunit) && !in_array($value['measurement'], $values_measurement)) {
            /* if not exist, add the item to $result array */
            $result[$key] = $value;
            /* and add altunit and measurement values to blacklist arrays */
            $values_altunit[] = $value['altunit'];
            $values_measurement[] = $value['measurement'];
        }
    }

    /* print result items */
    var_dump($result);

?>

基本上和我的答案逻辑差不多,但我认为黑名单是一个更好的名称 :P 除了这个答案需要一个新数组而不是从原始数组中取消设置值之外。 - Louis Loudog Trottier
是的,我们的答案相似,但我正在创建一个新数组而不是取消设置值...我们答案时间的差异是几秒钟 :) - Nomad Webcode
我喜欢保持我的memory_get_usage()尽可能低,这就是为什么我宁愿从现有的数组中取消值,而不是创建一个新的并复制值。个人偏好,只是说一下 :) 我仍然点赞你的答案 :P - Louis Loudog Trottier

1
这是一个简短的代码,可以给出唯一测量结果。
  <?php 

    $arr = array(
        "0"=> array        (
                "id" => 2,
                "altunit" => "%",
                "measurement" => "",
            ),

        "1"=> array        (
                "id" => 3,
                "altunit" => "",
                "measurement" => 6,
            ),

        "2"=> array        (
                "id" => 4,
                "altunit" => "%",
                "measurement" => "",
            ),

        "3"=> array        (
                "id" => 5,
                "altunit" => "",
                "measurement" => 6,
            ),

        "4"=> array        (
                "id" => 6,
                "altunit" => "",
                "measurement" => 6,
            )

    );

    $unique_measure = $new_array  = array();
    foreach($arr as $sup_key => $sup_val){
        foreach($sup_val as $sub_key => $sub_val){
            if(!in_array($sup_val['measurement'], $unique_measure)){
                array_push($unique_measure, $sup_val['measurement']);
                array_push($new_array,$sup_val);

            }

        }
    }

    print_r($new_array);
?>

Output :

  Array
    (
        [0] => Array
            (
                [id] => 2
                [altunit] => %
                [measurement] => 
            )

        [1] => Array
            (
                [id] => 3
                [altunit] => 
                [measurement] => 6
            )

    )   

尝试这段代码,它可能会起作用。

解决问题的另一种方法是使用 unset(your_array_key) 从主数组中删除特定键,在同一代码中实现。


1
尝试一下,这可能会对你有所帮助。
function remove_dup($array, $keys )
{
    $out = array();

    foreach($array as $sub)
    {
        if(empty($out))
        {   
            $out[] = $sub;
            continue;
        }

        foreach($keys as $key)
        {   
            if($flag=in_array( $sub[$key],array_map(function($e) use($key){ return $e[$key];}, $out)) )
                break;
        }

        if(!$flag)
            $out[] = $sub;
    }

    return $out;
}

// Usage
print_r( remove_dup($array, array('altunit','measurement') ) );

测试

[akshay@localhost tmp]$ cat test.php 
<?php

function remove_dup($array, $keys )
{
    $out = array();

    foreach($array as $sub)
    {
        if(empty($out))
        {   
            $out[] = $sub;
            continue;
        }

        foreach($keys as $key)
        {   
            if($flag=in_array( $sub[$key],array_map(function($e) use($key){ return $e[$key];}, $out)) )
                break;
        }

        if(!$flag)
            $out[] = $sub;
    }

    return $out;
}

$array = array(
        "0"=> array      (
                "id" => 2,
                "altunit" => "%",
                "measurement" => "",
            ),

        "1"=> array        (
                "id" => 3,
                "altunit" => "",
                "measurement" => 6,
            ),

        "2"=> array        (
                "id" => 4,
                "altunit" => "%",
                "measurement" => "",
            ),

        "3"=> array        (
                "id" => 5,
                "altunit" => "",
                "measurement" => 4,
            ),

        "4"=> array        (
                "id" => 6,
                "altunit" => "",
                "measurement" => 6,
            )

    );

print_r( remove_dup($array, array('altunit','measurement') ) );


?>

输出

[akshay@localhost tmp]$ php test.php 
Array
(
    [0] => Array
        (
            [id] => 2
            [altunit] => %
            [measurement] => 
        )

    [1] => Array
        (
            [id] => 3
            [altunit] => 
            [measurement] => 6
        )

)

0
你真正想要的是一个集合,而不是一个数组。所以如果你不能在第一时间修复构建数组的方式(我猜这可能来自于一个SQL查询,但更改起来会少很多代码),那么你有两个选项可以在PHP中创建映射集合。
  1. 你可以使用SplObjectStorage
  2. 你可以使用一个Array,其中键是集合的序列化表示

第一种方法看起来像这样...

$set = new SplObjectStorage();

$arr = [
    0 => [
        'id'          => '2',
        'altunit'     => '%',
        'measurement' => NULL,
    ],
    1 => [
        'id'          => '3',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
    2 => [
        'id'          => '4',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
    3 => [
        'id'          => '5',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
    4 => [
        'id'          => '6',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
];

foreach($arr as $part) {
    if (isset($part['altunit'])) { // ignore if blank
        $key = (object) $part;
        $set->attach($key); // attach the set
    }
}

// Now you have...
foreach($set as $value) {
    var_dump($value);
}

这将为您提供...

object(stdClass)#2 (3) {
  ["id"]=>
  string(1) "2"
  ["altunit"]=>
  string(1) "%"
  ["measurement"]=>
  NULL
}

第二种方法是使用数组,其中数组键表示集合的序列化版本,代码如下:...
$set = [];

$arr = [
    0 => [
        'id'          => '2',
        'altunit'     => '%',
        'measurement' => NULL,
    ],
    1 => [
        'id'          => '3',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
    2 => [
        'id'          => '4',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
    3 => [
        'id'          => '5',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
    4 => [
        'id'          => '6',
        'altunit'     => NULL,
        'measurement' => '6',
    ],
];

foreach($arr as $part) {
    if (isset($part['altunit'])) { // ignore if blank
        $key = "{$part['altunit']}\0{$part['measurement']}";
        $set[$key] = $part; // attach the set
    }
}

// Now you have...
foreach($set as $value) {
    var_dump($value);
}

这将会给你...

array(3) {
  ["id"]=>
  string(1) "2"
  ["altunit"]=>
  string(1) "%"
  ["measurement"]=>
  NULL
}

N.B

但是,如果这是来自SQL查询的结果集,通过修改查询以使用WHERE NOT NULLGROUP BY子句,您很可能可以更有效地完全消除去重过程。


0
You can try this also
 <?php
      $keys    = array_map(function ($i) { return $i; }, $array);
      $dumparr = array_combine($keys, $array);
      $result  = array_values($deduped);
      print_r($result);
?>

它基本上是做什么的? - Akshay Hegde

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