在关联数组中查找max和min键

时间:2012-11-15 07:02:11

标签: php arrays associative-array

我有关联数组,如

array
{
    [company 1]=>array
                      (
                        [1981] => 1
                        [1945] => 3
                      )
   [company 2]=>array
                    (
                       [1990] => 18
                       [2005] => 13
                    )
   [company 3]=>array
                    (
                       [1950] => 6
                       [2012] => 9
                    )
}

我希望得到最低和最高的关键,即1945年和2012年。 我怎样才能实现这一目标?我已经搜索了stackoverflow并且Hightest value of an associative array是最接近的可能性但是它给出了最小值和最大值,我想要最小和最大键。

**我不想使用foreach循环**

4 个答案:

答案 0 :(得分:4)

如果你真的讨厌foreach,这是一个解决方案:

$arr = array(
  "Company 1" => array(
    "1981" => 1,
    "1945" => 3
  ),

  "Company 2" => array(
    "1990" => 18,
    "2005" => 13
  ),

  "Company 3" => array(
    "1950" => 6,
    "2012" => 9
  )
);


$arr = array_map("array_keys", $arr);
$arr = array_reduce($arr, "array_merge", array());

您的$arr最终会像这样:

Array
(
    [0] => 1981
    [1] => 1945
    [2] => 1990
    [3] => 2005
    [4] => 1950
    [5] => 2012
)

现在,您可以使用min()max()函数或sort()轻松获得最高和最低价值。

sort($arr);
echo end($arr); /*highest value; actual output: 2012*/
echo reset($arr); /*lowest value; actual output: 1945*/

答案 1 :(得分:1)

ksort($array);
$min = reset($array);
end($array);
$max = key($array);

修改: 这适用于简单数组。你有2级结构,所以几乎不可能避免循环它。

但是,如果你有这么多条目甚至foreach太慢,你可能应该重新考虑你的方法。例如,将此列表放入数据库并使用SQL为您做繁重的工作。

到底是怎么回事?设置MySQL或PostgreSQL的实例(我个人更喜欢Postgres,原因很多),创建数据库,创建具有如下结构的表:

CREATE TABLE mytable (
    mytable_id INTEGER PRIMARY KEY,
    company VARCHAR(16),
    year INTEGER,
    value INTEGER,
    -- put some more metadata...
)

从技术上讲,您应该规范化数据库并为每个对象创建单独的表(例如公司的表,客户,订单等等),但您可以稍后再讨论。

在您要搜索的列上创建索引(例如年份,公司等):

CREATE INDEX mytable_year_idx ON mytable (year);
...

最后,在您的PHP脚本中,连接到数据库并查询您想要的内容,如下所示:

SELECT min(year) AS min_year,
       max(year) AS max_year
FROM mytable

答案 2 :(得分:1)

试试这个:
使用foreach。

        $array = array("company 1" => array(1981 => 1, 1945 =>3),
                        "company 2" => array(1990 => 18, 2005 => 13),
                        "company 3" => array(1950 => 6, 2012 =>9),
        );

        $keys = array();
        foreach($array as $arr)
        {
            foreach( array_keys($arr) as $val)
            {
                array_push($keys, $val);
            }
        }
        sort($keys);
        $min = $keys[0];
        $max = $keys[count($keys)-1];

没有foreach:

        global $keys;
        $GLOBALS['keys'] = array();
        function sortme($arr)
        {
            is_array($arr)? array_map("sortme",array_keys($arr)): array_push($GLOBALS['keys'], $arr);

        }
        array_map("sortme",$array);
        sort($GLOBALS['keys']);
        $min = $GLOBALS['keys'][0];
        $max = $GLOBALS['keys'][count($GLOBALS['keys'])-1];
        echo "min = ".$min . "<br/>max = ".$max;

答案 3 :(得分:0)

因为,您的输入数组为“ 非常大”并且“ 消耗了很多时间”,这恰恰是使用一组简单的语言构造来一次遍历数据集。

使用多个数组函数可能看起来更简洁或更聪明,但是它们将对数据进行多次传递,并且总是消耗比绝对必要更多的资源。

由于您的数据需要处理多年,因此您可以使用“魔术数字”将业务逻辑构建到代码逻辑中-假设您永远不会遇到负数年份或10,000年及以后的年份。

如果您想要一种与业务无关的方法,则可以通过将第一行移出输入数组并获取该子数组的min和max键来播种默认的min和max值。

魔术数字代码:(Demo

$minYear = 9999;
$maxYear = 0;
foreach ($array as $row) {
    foreach ($row as $year => $value) {
        if ($year > $maxYear) {
            $maxYear = $year;
        }
        if ($year < $minYear) {
            $minYear = $year;
        }
    }
}
echo "MinYear = $minYear, MaxYear = $maxYear";
// MinYear = 1945, MaxYear = 2012

已更改的默认代码:(Demo

if ($array) {
    $firstKeys = array_keys(array_shift($array));
    $minYear = min($firstKeys);
    $maxYear = max($firstKeys);
} else {
    $minYear = null;
    $maxYear = null;
}
foreach ($array as $row) {
    foreach ($row as $year => $value) {
        if ($year > $maxYear) {
            $maxYear = $year;
        } elseif ($year < $minYear) {
            $minYear = $year;
        }
    }
}
echo "MinYear = $minYear, MaxYear = $maxYear";

请注意,移位代码段专门处理了第一个数据集以获取默认值-这需要一些额外的行-但由于elseif而具有更高的潜在效率。

这两种技术都不使用迭代函数调用,因此实际上可以确保它们比函数技术执行得更快。