在关联数组中查找最大和最小键

问题描述 投票:1回答:4

我有类似数组

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循环**

php arrays associative-array
4个回答
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
投票

尝试这个:使用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;

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

0
投票

因为您的输入数组是“ 非常大”和“ 消耗很多时间”,这正是使用一组简单的语言构造来迭代输入的理由。一次通过数据集。

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

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

如果您希望采用与业务无关的方法,则可以通过将第一行移出输入数组并获取该子数组的最小键和最大键来播种默认的最小和最大值。

魔术数字代码:(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而享有更高的潜在效率。

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

© www.soinside.com 2019 - 2024. All rights reserved.