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

时间:2022-12-20 21:30:14

I want to remove duplicates where either measurement or altunit matches another array, but ignoring if they're blank.

我想删除重复项,其中测量或altunit匹配另一个数组,但忽略它们是否为空。

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
        )

)

Becomes

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

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

)

Best I can come up with is:

我能想出的最好的是:

$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'];

But this only works for measurement, and removes the id and altunit keys.

但这仅适用于测量,并删除id和altunit键。

6 个解决方案

#1


3  

Humm, Make an array of 'knowed value' for measurement and altunit and then check it it exist on the rest of the values.

嗯,为测量和altunit创建一个“知道值”数组,然后检查它是否存在于其余值上。

something like:

$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'];
  }
}

Sorry if any typo but thins might help you wrap your head around the solution to your problem.

对不起,如果有任何错误,但可能会帮助你解决你的问题的解决方案。

#2


2  

You can try this code:

你可以试试这段代码:

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

?>

#3


1  

This is a short code that can give the result for unique measurements

这是一个简短的代码,可以给出独特测量的结果

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

    )   

try this code. it may do the trick.

试试这段代码。它可以做到这一点。

One More approach to your problems solution can be removing that particular key from the main array using unset(your_array_key) will do the trick in the same code.

问题解决方案的另一种方法是使用unset(your_array_key)从主数组中删除该特定键将在相同的代码中执行。

#4


1  

Try, this may help you

试试,这可能会对你有所帮助

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

Test

[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') ) );


?>

Output

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

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

)

#5


0  

What you really want is a set, not an array. So if you can't fix the way you're building the array in the first place (my guess is this came from an SQL query, which would be a lot less code to rectify) you have two options for creating mapped sets in PHP.

你真正想要的是一个集合,而不是一个数组。所以,如果你不能修改你首先构建数组的方式(我猜这是来自一个SQL查询,这将是很少的代码来纠正)你有两个选项用于在PHP中创建映射集。

  1. You could use SplObjectStorage
  2. 您可以使用SplObjectStorage

  3. You could use an Array with the key as a serialized representation of the set
  4. 您可以使用带有键的Array作为集合的序列化表示

The first approach would look something like this...

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

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

This would give you...

这会给你......

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

The second approach, using an array, where the array key represents a serialized version of the set would look something like this...

第二种方法,使用数组,其中数组键表示集合的序列化版本看起来像这样......

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

And that would give you...

这会给你......

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

N.B

But, if this is a result set from an SQL query it's quite possible you could just more effectively eliminate the de-duplication process entirely by modifying the query to use WHERE NOT NULL and GROUP BY clauses instead.

但是,如果这是SQL查询的结果集,则很可能通过修改查询以使用WHERE NOT NULL和GROUP BY子句来完全消除重复数据删除过程。

#6


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

#1


3  

Humm, Make an array of 'knowed value' for measurement and altunit and then check it it exist on the rest of the values.

嗯,为测量和altunit创建一个“知道值”数组,然后检查它是否存在于其余值上。

something like:

$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'];
  }
}

Sorry if any typo but thins might help you wrap your head around the solution to your problem.

对不起,如果有任何错误,但可能会帮助你解决你的问题的解决方案。

#2


2  

You can try this code:

你可以试试这段代码:

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

?>

#3


1  

This is a short code that can give the result for unique measurements

这是一个简短的代码,可以给出独特测量的结果

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

    )   

try this code. it may do the trick.

试试这段代码。它可以做到这一点。

One More approach to your problems solution can be removing that particular key from the main array using unset(your_array_key) will do the trick in the same code.

问题解决方案的另一种方法是使用unset(your_array_key)从主数组中删除该特定键将在相同的代码中执行。

#4


1  

Try, this may help you

试试,这可能会对你有所帮助

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

Test

[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') ) );


?>

Output

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

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

)

#5


0  

What you really want is a set, not an array. So if you can't fix the way you're building the array in the first place (my guess is this came from an SQL query, which would be a lot less code to rectify) you have two options for creating mapped sets in PHP.

你真正想要的是一个集合,而不是一个数组。所以,如果你不能修改你首先构建数组的方式(我猜这是来自一个SQL查询,这将是很少的代码来纠正)你有两个选项用于在PHP中创建映射集。

  1. You could use SplObjectStorage
  2. 您可以使用SplObjectStorage

  3. You could use an Array with the key as a serialized representation of the set
  4. 您可以使用带有键的Array作为集合的序列化表示

The first approach would look something like this...

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

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

This would give you...

这会给你......

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

The second approach, using an array, where the array key represents a serialized version of the set would look something like this...

第二种方法,使用数组,其中数组键表示集合的序列化版本看起来像这样......

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

And that would give you...

这会给你......

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

N.B

But, if this is a result set from an SQL query it's quite possible you could just more effectively eliminate the de-duplication process entirely by modifying the query to use WHERE NOT NULL and GROUP BY clauses instead.

但是,如果这是SQL查询的结果集,则很可能通过修改查询以使用WHERE NOT NULL和GROUP BY子句来完全消除重复数据删除过程。

#6


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