duanjiao8007 2017-08-28 12:51 采纳率: 100%
浏览 62
已采纳

如何查找和删除php数组中几乎重复的行,这些行在一个键值上有所不同?

I have the following array (array is large):

Array ( 
   [0] => Array ( 
              [id] => 1 
              [timestamp] => 1503050400
              [name] =>  Event A
              [value] =>  )
   [1] => Array ( 
              [id] => 2 
              [timestamp] => 1503446400
              [name] => Event B 
              [value] =>  )
   [2] => Array ( 
              [id] => 2 
              [timestamp] => 1503446400
              [name] => Event B 
              [value] => 71 )
   [3] => Array ( 
              [id] => 3 
              [timestamp] => 1503720000
              [name] => Event C
              [value] => 12 )
   [4] => Array ( 
              [id] => 3 
              [timestamp] => 1503720000
              [name] => Event C 
              [value] =>  )

              ...
)

As you can see, some array keys (rows) have same ID, Timestamp, and Name, but different Value. I would like to find and unset($array[$key]) rows which meet the following conditions:

if array has keys with the same Name, Id and Timestamp, delete this keys, but leave only with Value != null

Looking something like this:

foreach ($array as $key => $row) {
  if ( ... ) {
    unset($array[$key]);
  }
else {}

}
print_r($array);

The output should be:

Array ( 
   [0] => Array ( 
              [id] => 1 
              [timestamp] => 1503050400
              [name] =>  Event A
              [value] =>  )
   [2] => Array ( 
              [id] => 2 
              [timestamp] => 1503446400
              [name] => Event B 
              [value] => 71 )
   [3] => Array ( 
              [id] => 3 
              [timestamp] => 1503720000
              [name] => Event C
              [value] => 12 )

              ...
)
  • 写回答

2条回答 默认 最新

  • doulan1073 2017-08-28 14:47
    关注

    You can use array_reduce() and array_filter():

    <?php
    
    $data = array(
        array(
            'id' => 1,
            'timestamp' => 1503050400,
            'name' => 'Event A',
            'value' => null,
        ),
        array(
            'id' => 2,
            'timestamp' => 1503446400,
            'name' => 'Event B',
            'value' => null,
        ),
        array(
            'id' => 2,
            'timestamp' => 1503446400,
            'name' => 'Event B',
            'value' => 71,
        ),
        array(
            'id' => 3,
            'timestamp' => 1503720000,
            'name' => 'Event C',
            'value' => 12,
        ),
        array(
            'id' => 3,
            'timestamp' => 1503720000,
            'name' => 'Event C',
            'value' => null,
        ),
    );
    
    /**
     * Reduce the array of items to an array of buckets, where
     * each bucket contains elements with the same
     *
     * - id
     * - timestamp
     * - name
     *
     * so that we can than take a look at the contents of the
     * individual buckets.
     */
    $buckets = array_reduce(
        $data,
        function (array $carry, array $item) {
            /**
             * create an index from
             *
             * - id
             * - timestamp
             * - name
             */
            $index = serialize(array(
                'id' => $item['id'],
                'timestamp' => $item['timestamp'],
                'name' => $item['name'],
            ));
    
            /**
             * initialize empty bucket if we don't have one yet for this index
             */
            if (!array_key_exists($index, $carry)) {
                $carry[$index] = array();
            }
    
            /**
             * add item to bucket
             */
            $carry[$index][] = $item;
    
            return $carry;
        },
        array()
    );
    
    /**
     * Reduce the content of the buckets to elements that match the requirements.
     */
    $filtered = array_reduce(
        $buckets,
        function (array $carry, array $items) {
            /**
             * if we have only one item in the bucket, let's take it
             */
            if (1 === count($items)) {
                $carry[] = array_shift($items);
    
                return $carry;
            }
    
            /**
             * find all items where the value is not null
             */
            $withoutNullValue = array_filter($items, function (array $item) {
                return array_key_exists('value', $item) && null !== $item['value'];
            });
    
            /**
             * if we have any items where the value is not null, take all of them
             */
            if (0 < count($withoutNullValue)) {
                $carry = array_merge(
                    $carry,
                    $withoutNullValue
                );
    
                return $carry;
            }
    
            /**
             * if all of the items have a value of null, let's just take the first
             */
            $carry[] = array_shift($items);
    
            return $carry;
        },
        array()
    );
    
    var_dump($filtered);
    

    For reference, see:

    For an example, see:

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)