最近我接受了面试。我有两个任务:
1)重构JavaScript代码
// The library 'jsUtil' has a public function that compares 2 arrays, returning true if
// they're the same. Refactor it so it's more robust, performs better and is easier to maintain.
/**
@name jsUtil.arraysSame
@description Compares 2 arrays, returns true if both are comprised of the same items, in the same order
@param {Object[]} a Array to compare with
@param {Object[]} b Array to compare to
@returns {boolean} true if both contain the same items, otherwise false
@example
if ( jsUtil.arraysSame( [1, 2, 3], [1, 2, 3] ) ) {
alert('Arrays are the same!');
}
*/
// assume jsUtil is an object
jsUtil.arraysSame = function(a, b) {
var r = 1;
for (i in a) if ( a[i] != b[i] ) r = 0;
else continue;
return r;
}
2)重构检查闰年的PHP函数
<?php
/*
The class 'DateUtil' defines a method that takes a date in the format DD/MM/YYYY, extracts the year
and works out if it is a leap year. The code is poorly written. Refactor it so that it is more robust
and easier to maintain in the future.
Hint: a year is a leap year if it is evenly divisible by 4, unless it is also evenly
divisible by 100 and not by 400.
*/
class DateUtil {
function notLeapYear ($var) {
$var = substr($var, 6, 4);
if (! ($var % 100) && $var % 400) {
return 1;
}
return $var % 4;
}
}
$testDates = array('03/12/2000', '01/04/2001', '28/01/2004', '29/11/2200');
/* the expected result is
* 03/12/2000 falls in a leap year
* 01/04/2001 does not fall in a leap year
* 28/01/2004 falls in a leap year
* 29/11/2200 does not fall in a leap year
*/
?>
<? $dateUtil = new DateUtil(); ?>
<ul>
<? foreach ($testDates as $date) { ?>
<li><?= $date ?> <?= ($dateUtil->notLeapYear($date) ? 'does not fall' : 'falls') ?> in a leap year</li>
<? } ?>
</ul>
我认为我应对这项任务,但我不太确定,我仍然没有得到他们的答复,而且已经过了一个星期。你能举例说明你对这项任务的态度吗?我真的很感激。稍后我可以发布我的解决方案/代码。
好的,这是我对问题的回答。
<?php // Always use full/long openning tags not
$start = microtime(true);
class DateUtil {
/**
* The date could be used in other
* class methods in the future.
* Use just internally.
**/
var $_date;
/**
* The constructor of the class takes
* 1 argument, date, as a string and sets
* the object parameter _date to be used
* internally. This is compatable only in PHP5
* for PHP4 should be replaced with function DateUtil(...)
*/
public function __construct( $date = '' ) {
$this->_date = $date;
}
/**
* Setter for the date. Currently not used.
* Also we could use _set magical function.
* for PHP5.
**/
public function setDate( $date = '' ) {
$this->_date = $date;
}
/**
* Gettre of the date. Currently not used.
* Also we could use _get magical function.
* for PHP5.
**/
public function getDate() {
return $this->_date;
}
public function isLeapYear( $year = '' ) {
// all leap years can be divided through 4
if (($year % 4) != 0) {
return false;
}
// all leap years can be divided through 400
if ($year % 400 == 0) {
return true;
} else if ($year % 100 == 0) {
return false;
}
return true;
}
}
$dates = array('03/12/2000', '01/04/2001', '30/01/2004', '29/11/2200');
$dateUtil = new DateUtil();
foreach($dates as $date) {
/**
* This processing is not done in the class
* because the date format could be different in
* other cases so we cannot assume this will allways
* be the format of the date
*
* The php function strtotime() was not used due to
* a bug called 2K38, more specifically dates after and 2038
* are not parsed correctly due to the format of the UNIX
* timestamp which is 32bit integer.
* If the years we use are higher than 1970 and lower
* than 2038 we can use date('L', strtotime($date));
**/
$year = explode('/', $date);
$year = $year[2];
$isLeap = $dateUtil->isLeapYear($year);
echo '<pre>' . $date . ' - ';
echo ($isLeap)? 'Is leap year': 'Is not leap year';
echo '</pre>';
}
echo 'The execution took: ' . (microtime(true) - $start) . ' sec';
?>
的JavaScript
/***************************************************/
jsUtil = new Object();
jsUtil.arraysSame = function(a, b) {
if( typeof(a) != 'object') {
// Check if tepes of 'a' is object
return false;
} else if(typeof(a) != typeof(b)) {
// Check if tepes of 'a' and 'b' are same
return false;
} else if(a.length != b.length) {
// Check if arrays have different length if yes return false
return false;
}
for(var i in a) {
// We compare each element not only by value
// but also by type so 3 != '3'
if(a[i] !== b[i]) {
return false;
}
}
return true;
}
// It will work with associative arrays too
var a = {a:1, b:2, c:3};
var b = {a:1, b:2, c:3}; // true
var c = {a:1, b:2, g:3}; // false
var d = {a:1, b:2, c:'3'}; // false
var output = '';
output += 'Arrays a==b is: ' + jsUtil.arraysSame( a, b );
output += '\n';
output += 'Arrays a==c is: ' + jsUtil.arraysSame( a, c );
output += '\n';
output += 'Arrays a==d is: ' + jsUtil.arraysSame( a, d );
alert(output);
答案 0 :(得分:5)
使用for
循环而不是for...in
迭代数组。如果数组不同,您希望尽快返回,因此从长度比较开始并立即返回您遇到两个数组之间不同的元素。使用严格不等运算符!==
比较它们。向后遍历数组以获得速度,并通过将a
的长度分配给i
并重用i
作为迭代变量来最小化所需的变量数。
此代码假定参数a
和b
都已提供,并且都是Array
个对象。这似乎暗示了这个问题。
var jsUtil = jsUtil || {};
jsUtil.arraysSame = function(a, b) {
var i = a.length;
if (i != b.length) return false;
while (i--) {
if (a[i] !== b[i]) return false;
}
return true;
};
答案 1 :(得分:3)
对于PHP版本:
class DateUtil {
function LeapYear ($var) {
$date = DateTime::CreateFromFormat($var, 'd/m/Y');
return($date->format('L')); // returns 1 for leapyear, 0 otherwise
}
function notLeapYear($var) {
return(!$this->LeapYear($var)) {
}
}
答案 2 :(得分:1)
对于第一个问题,我可以帮助你:
var jsUtil = jsUtil || {};
jsUtil.arraysSame = function(a, b){
//both must be arrays
if (!a instanceof Array || !b instanceof Array) {
return false;
}
//both must have the same size
if (a.length !== b.length) {
return false;
}
var isEquals = true;
for (var i = 0, j = a.length; i < j; i++) {
if (a[i] !== b[i]) {
isEquals = false;
i = j; //don't use break
}
}
return isEquals;
}
我包含了类型检查并使事情变得更加清晰。
答案 3 :(得分:0)
在我看来,使用内置的预定义功能总是最好的选择。
1)使用将数组转换为字符串的函数。有许多这些可用,根据您已经使用的库,您可能想要使用不同的库。您可以在Json.org
找到一个jsUtil.arraysSame = function(a, b) {
return JSON.stringify(a) == JSON.stringify(b);
}
2)使用PHP的内置日期函数和strtotime
class DateUtil {
function notLeapYear ($var) {
return (date( 'L', strtotime( $var)) == "0");
}
}
答案 4 :(得分:0)
in
进行迭代,在扩展标准类型的原型时会非常失败