此函数如何从数组返回第一个重复对象?

时间:2019-03-07 12:53:06

标签: php

我在Code-Signal(您可以在其中执行一些与编程相关的任务的网站)上找到一项任务(或更像是一个挑战)。谷歌在一次采访中问了这个特殊任务:

如果您想自己尝试一下:Code-Fight

解决问题后,您可以查看其他解决方案。

我的任务是“在数组中找到第一个被骗对象”。我设法做到了(我会指出路),但是我对结果不满意。在研究了最佳解决方案之后,我感到困惑,因为我不知道那里发生了什么。

这是(a)给出的示例输入数组

const AWS = require('aws-sdk');

exports.handler = (event) => {
    AWS.config.update({region: 'eu-west-1'});
    var cw = new AWS.CloudWatch({apiVersion: '2010-08-01'});

    var alarmStatus = {};
    cw.describeAlarms({}, function(err, data) {
        if (err) {
            console.log("Error", err);
        } else {
            data.MetricAlarms.forEach(function (item, index, array) {
                var pair = {[item.AlarmName]: item.StateValue};
                alarmStatus = {...alarmStatus, ...pair};
                console.log(alarmStatus);
            });
        }
    });

    const response = {
        statusCode: 200,
        body: JSON.stringify(alarmStatus),
    };
    return response;
};

我的解决方案:

$a = [2, 1, 3, 5, 3, 2]

它适用于每个测试用例,我解决了挑战。但是,最佳解决方案是:

function firstDuplicate($a) {

    $onlyDupesArray= array();
    $countedValues = array_count_values($a);

    // remove all entries which are only once in the array
    foreach($a as $k => $v) {
        if($countedValues[$v] > 1) {
            $onlyDupesArray[$v] = $v;
        }
    }

    // get rid of dupes
    $uniqueDupesArray = array_unique($onlyDupesArray);
    $firstEncounter = PHP_INT_MAX;

    foreach($uniqueDupesArray as $k => $v) {
        if(array_keys($a, $v)[1] < $firstEncounter) {
            $firstEncounter = array_keys($a, $v)[1];
        }
    }

    if(is_null($a[$firstEncounter])) {
        return -1;
    } else {
        return $a[$firstEncounter];
    }
}

我知道variable variable是什么,但直到现在还没有在野生动物中看到。

references变量在这里做什么?这怎么还骗人?是否可以通过某种方式比较这种键入是否已经存在某个键的值? function firstDuplicate($a) { foreach ($a as $v) if ($$v++) return $v; return -1; } 是否引用数组中的键?

不用说,我更喜欢这种方法。似乎更有效,更易于维护。

这是“惯例”吗?

2 个答案:

答案 0 :(得分:2)

它正在创建编号变量。 $ 2,$ 1,$ 3等。

foreach中的

$ v包含当前数字2。通过执行$test = 2; echo $$test,我们可以立即看到$ 2中的内容。通常是空的。现在,通过执行$$ v ++,它将返回当前值(空值或实际上不存在变量),但是++会将“ 1”放入其中。整个语句本身将返回0,因为++不在变量的前面。

考虑以下代码:

$arr = [2, 1, 3, 5, 3, 2];
foreach($arr as $v) 
{
  $$v++;
}
$test = 3; 
echo $$test;

这将显示$ 3的值等于2,因为我们对$ 3进行了2倍++的操作。

这很奇怪的唯一原因是通常您不能使用以数字开头的变量。也许这样更清楚?:

$arr = [2, 1, 3, 5, 3, 2]; 
foreach($arr as $v) 
{
  $v='a'.$v;
  $$v++;
}
echo "a3 = $a3\n"; // 2
echo "a2 = $a2\n"; // 2
echo "a1 = $a1\n"; // 1
echo "a5 = $a5\n"; // 1

回答问题“这是“惯例”吗?”。不,我个人不会使用变量变量,因为在某些情况下这可以被视为安全问题。我个人更喜欢以下解决方案,该解决方案是相同的,但是使用数组,并且不会引发通知:

function firstDuplicate($a) {
    $arr = []; 
    foreach ($a as $v) 
        if (in_array($v, $arr))
            return $v; 
        else
            $arr[] = $v; 
    return -1; 
}

不过,可变变量解决方案是一种创新的解决方案!

答案 1 :(得分:0)

通过使用额外的$(变量变量)指定变量,PHP将创建“隐藏/伪数组”。 运行时,每个索引都用“ 0”填充:

第一次跑步后,你会得到类似的东西

$array[2] = 0;

下一次运行后,索引1会被填充:

$array[1] = 0;
$array[2] = 0;

由于将“ 0”视为假,因此您的条件在第一个重复项(3)之后变为有效:

$array[1] = 0;
$array[2] = 0;
$array[3] = 1; // <-- TRUE
$array[5] = 0;