在PHP中从关联数组的数组中删除重复项/排序

3

我有一个关联数组的数组

aa[] = ('Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 );
aa[] = ('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 );
aa[] = ('Tires'=>34,  'Oil'=>55, 'Spark Plugs'=>44 );
aa[] = ('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 );
aa[] = ('Tires'=>34,  'Oil'=>55, 'Spark Plugs'=>433 );
aa[] = ('Tires'=>23,  'Oil'=>33, 'Spark Plugs'=>44 );

两个问题

  1. 如何按照字段“Oil”删除重复项 是否有可以提供回调函数作为自定义比较器的array_unique?

  2. 如何按照自定义字段“Spark Plugs”排序

5个回答

1
  1. 我不知道有什么函数可以做到这一点。你需要对数组的值进行foreach循环,并手动进行唯一性检查。

  2. 使用usort()函数并提供自定义比较器。


1

不必手动进行常规的重复检查,我做了以下操作:


$aa2 = array()
foeach($aa as $key => $value) { $aa2[$value['Oil']] = $value; } $aa = $aa2;

然后按照键值进行排序...


0

你确实可以使用array_filter来过滤你的数据:

$bb = array_filter($aa, function($item) {
    static $tmp = array();

    if ($filter = !in_array($item['Oil'], $tmp)) {
        $tmp[] = $item['Oil'];
    }

    return $filter;
});

这个函数使用一个静态变量来“记住”已经返回的油。这个方法可行,因为$tmp只在执行array_filter期间使用。如果你将其封装成一个函数并且多次调用它,$tmp总是会在提供给array_filter的函数的第一次调用中为空数组。

第二个任务——排序可以使用自定义排序函数的usort完成:

usort($bb, function($a, $b) {
    return ($a['Spark Plugs'] > $b['Spark Plugs']
            ? 1
            : -1);
});

0

使用这种方式删除重复项的问题在于,如何确定哪些值保留,因为您正在谈论部分唯一性。

下面的解决方案仅保留按索引顺序出现的第一个值。 它并不完美,但它有效。

<?php

$aa = array();
$aa[] = array('Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 );
$aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 );
$aa[] = array('Tires'=>34,  'Oil'=>55, 'Spark Plugs'=>44 );
$aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 );
$aa[] = array('Tires'=>34,  'Oil'=>55, 'Spark Plugs'=>433 );
$aa[] = array('Tires'=>23,  'Oil'=>33, 'Spark Plugs'=>44 );

echo '<pre>';
print_r( arrayUniqeBySubKey( $aa, 'Oil' ) );
echo '</pre>';

function arrayUniqeBySubKey( $array, $key )
{
  $indexAggregates = array();

  foreach ( $array as $idx => $subArray )
  {
    $indexAggregates[$subArray[$key]][] = $idx;
  }

  foreach ( $indexAggregates as $originalIndexes )
  {
    $numOriginals = count( $originalIndexes );
    if ( 1 == $numOriginals )
    {
      continue;
    }
    for ( $i = 1; $i < $numOriginals; $i++ )
    {
      unset( $array[$originalIndexes[$i]] );
    }
  }
  return $array;
}

0

对于问题1,我认为array_filter是你需要的。

而且,就像Brian所说,你可以使用usort来解决第二个问题。


array_filter的问题在于它需要从比较器内部知道是否存在其他具有该值的条目。我想不到任何比自己迭代更简单或更清晰的方法来解决这个问题。 - Brian Ramsay

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