重构JavaScript和PHP代码[求职面试]

Ale*_*kov 2 javascript php refactoring

最近我接受了面试.我有两个任务:

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;
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

我认为我应对这项任务,但我不太确定,我仍然没有得到他们的答复,而且已经有一周了.你能举例说明你对这项任务的态度吗?我真的很感激.稍后我可以发布我的解决方案/代码.

好的,这是我对问题的回答.

<?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';
?>
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

Tim*_*own 5

使用for循环而不是使用循环迭代数组for...in.如果数组不同,您希望尽快返回,因此从长度比较开始并立即返回您遇到两个数组之间不同的元素.使用严格不等运算符比较它们!==.向后遍历数组以获得速度,并最小化分配a长度i并重用i为迭代变量所需的变量数.

此代码假定参数ab都是提供的并且都是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;
};
Run Code Online (Sandbox Code Playgroud)

  • Downvoter:请解释一下.这段代码是正确的,我已经解释过了. (3认同)