过滤关联数组以在元素的值大于其相邻元素的值时保留元素

Filter associative array to keep elements when their value is greater than their neighboring elements' values

我有一个关联数组,我需要从中创建一个新数组。我的目标是新阵列的峰值。对于要选择到新数组的值,它需要高于数组中的前一个值和下一个值。

我在网上搜索并找到了一个可以处理索引数组情况的函数 - 但不能处理关联数组。这是我想要的:

$array = array('a' => 0, 'b' => 2, 'c' => 1, 'd' => 2, 'e' => 3);
$result = array('b' => 2, 'e' => 3);

可用于索引数组的函数如下所示:

$a = array(0, 2, 1, 2, 3);
$b = array_filter($a, function($v, $k) use($a) {
  return $k > 0 && $v > $a[$k-1] && $k + 1 < count($a) && $v > $a[$k+1];
}, ARRAY_FILTER_USE_BOTH );

此函数也不包含最后一个值。

如果你真的想得到边境物品,你应该改变条件。但是一种方法可能是使用键数组来获取上一个和下一个项目

$array = array('a' => 0, 'b' => 2, 'c' => 1, 'd' => 2, 'e' => 3);
$keys = array_keys($array);

$b = array_filter($array, function($v, $k) use($array, $keys) {
  $k = array_search($k, $keys);
  return $k > 0 && $v > $array[$keys[$k-1]] && $k + 1 < count($keys) && $v > $array[$keys[$k+1]];
}, ARRAY_FILTER_USE_BOTH );

print_r($b);

我在@splash58 工作。谢谢你。我有 none 自己尝试的次数较少,但也有效 - 但我不知道哪种解决方案最有效。

$result = array();
$value1 = NULL;

foreach (array_reverse($array) as $key => $value) {
  if ($value > $value1) {
    $result[$key] = $value;
  }
  $value1 = $value;
}

“$value1 = NULL”是否有必要?

这可以通过零迭代函数调用来完成。

在循环之前通过为输入数组的键分配索引来声明查找数组 -- array_keys().

然后在尝试访问 non-existent 元素时,在循环中使用条件回退值和空合并。

  1. ($i ? $array[$keys[$i - 1]] : $array[$key] - 1) 表示:如果 $i 不为零,则通过当前键之前一个位置的键访问输入数组中的值。否则,$i 等于零,这意味着没有更早的值,因此回退到当前值减一以保证它在比较中会更小。

  2. ($array[$keys[$i + 1] ?? -1] ?? $array[$key] - 1)表示:尝试访问查找数组中的下一个key,如果不存在,则使用保证不存在的负数。实际上,当 $i 是循环中的最后一个索引时,将没有下一个键,因此再次回退到当前值减一。

这应该总是优于任何进行迭代函数调用的脚本。

代码:(Demo)

$array = ['a' => 0, 'b' => 2, 'c' => 1, 'd' => 2, 'e' => 3];

$keys = array_keys($array);
foreach ($keys as $i => $key) {
    if ($array[$key] > ($i ? $array[$keys[$i - 1]] : $array[$key] - 1)
        && $array[$key] > ($array[$keys[$i + 1] ?? -1] ?? $array[$key] - 1)
    ) {
        $result[$key] = $array[$key];
    }
}
var_export($result);

输出:

array (
  'b' => 2,
  'e' => 3,
)

或者,如果您想改变输入数组,可以在循环中调用 unset() 并简单地反转条件逻辑。