20180803_ARTS_week06

Posted on 2018-08-03 in ARTS by yucongchen

Algorithm

/**
 * https://leetcode.com/problems/zigzag-conversion/description/
 * 
 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
var convert = function (s, numRows) {
    var step = numRows + numRows - 2
    var storeArray = new Array(numRows).fill("")
    var len = s.length  + step

    // 特别 case
    if (s.length < numRows || numRows < 2 || s.length < 2) {
        return s;
    }

    for(var i=0; i<len; i+=step) {
        for (var j=0; j<step; j+=1) {
            if(!s[i+j]){
                break;
            }
            if( j/numRows < 1 ) { // 前 numRows 个
                var pos = j%numRows
                storeArray[pos] += s[i+j]
            } else {
                storeArray.forEach(function(value, index, arr){
                    if( index + j == step ) {
                        storeArray[index] += s[i+j]
                    } else {
                        // storeArray[index] += " "
                    }
                })
            }
        }
    }

    return storeArray.join("")
};

console.log(convert("PAYPALISHIRING", 3)) // PAHNAPLSIIGYIR
/*
P   A   H   N
A P L S I I G
Y   I   R
*/
console.log(convert("PAYPALISHIRING", 4)) // PINALSIGYAHRPI
/*
P     I    N
A   L S  I G
Y A   H R
P     I
*/
console.log(convert("AB", 1)) // AB

这个是个比较不好的解法,就是像题目介绍里面那样先把这个『之』字形给做出来,然后再逐行读成字符串,但是通过这个比较好帮助我们理解这个题目。

这种就是找一些规律,可以按行构造,也可以按列构造,下面贴个按列构造的方法,还是比较容易懂的,有个 step 用来控制方向,表示要放到哪行的数组里面。

var convert = function (s, numRows) {
    // var result = [];
    var result = new Array(numRows).fill("");
    var step = 1, index = 0;

    // 排除一些特殊情况
    if (s.length < numRows || numRows < 2 || s.length < 2) {
        return s;
    }

    for (var i = 0; i < s.length; i++) {
        // if (result[index] === undefined) { // 排除掉一些特别情况之后,可以用 Array().fill() 来构造数组
        //     result[index] = '';
        // }
        result[index] += s[i];
        if (index === 0) {
            step = 1;
        } else if (index === numRows - 1) {
            step = -1;
        }
        index += step;
    }
    return result.join('');
};

console.log(convert("PAYPALISHIRING", 3))
console.log(convert("PAYPALISHIRING", 4))
console.log(convert("AB", 1))

Review

https://hackernoon.com/what-i-learned-from-doing-1000-code-reviews-fe28d4d11c71

What I learned from doing 1000 code reviews

作者结合他的个人经验给出了 4 条他常见的 code review 建议。

  1. 当出错的时候抛出异常。 这个比较好理解,举个例子,比如一个 Restfull 接口用来获取用户列表,当程序出错的时候没有报错,而是返回了一个空列表,并且 HTTP 返回码是 200。这个时候监控系统并不知道这个接口或者服务出错了,所以抛出一个异常,是更好的做法。

  2. 尽可能使用最特定的类型。 主要是从发现错误的数据,以及当发现数据有问题时提前报错。而且最特定的类型就是函数的签名,也是函数最好的注释。

  3. 使用 Optionals 代替 null。 这里主要是根据 Java 8 的 Optional 特性来说的。作者认为 Optional 有一个好处是不需要通过阅读文档来确定值是否可能不存在。

  4. “Unlift” methods whenever possible 这个 “Unlift" 我不是很理解,作者给了个例子: javascript // AVOID: T method(A param1, B param2, Optional<C> param3); // PREFER: T method(A param1, B param2, C param3); T method(A param1, B param2); // This method is clearly doing two things, it should be two methods // The same is true for boolean parameters 大意是作者建议不要在参数或者返回值用 Optional。

Tip

介绍下 ES5 中 Object.freeze() 方法。

Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。该方法返回被冻结的对象。

var obj = {
  prop: function() {},
  foo: 'bar'
};

// 新的属性会被添加, 已存在的属性可能
// 会被修改或移除
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;

// 作为参数传递的对象与返回的对象都被冻结
// 所以不必保存返回的对象(因为两个对象全等)
var o = Object.freeze(obj);

o === obj; // true
Object.isFrozen(obj); // === true

// 现在任何改变都会失效
obj.foo = 'quux'; // 静默地不做任何事
// 静默地不添加此属性
obj.quaxxor = 'the friendly duck';

// 在严格模式,如此行为将抛出 TypeErrors
function fail(){
  'use strict';
  obj.foo = 'sparky'; // throws a TypeError
  delete obj.quaxxor; // throws a TypeError
  obj.sparky = 'arf'; // throws a TypeError
}

fail();

// 试图通过 Object.defineProperty 更改属性
// 下面两个语句都会抛出 TypeError.
Object.defineProperty(obj, 'ohai', { value: 17 });
Object.defineProperty(obj, 'foo', { value: 'eit' });

// 也不可能设置属性
// 下面两个语句都会抛出 TypeError.
Object.setPrototypeOf(obj, { x: 20 })
obj.__proto__ = { x: 20 }

在 Vue 中这个有一个好处就是如果你有一个 Object,并且不会修改,使用 Object.freeze() 可以让性能大幅提升。根据 https://juejin.im/entry/57a83edd128fe100549006aa 这里说的,性能提升有 5~10 倍

new Vue({
    data: {
        // vue 不会对 list 里的 object 做 getter、setter 绑定
        list: Object.freeze([
            { value: 1 },
            { value: 2 }
        ])
    },
    created () {
        // 界面不会有响应
        this.list[0].value = 100;

        // 下面两种做法,界面都会响应
        this.list = [
            { value: 100 },
            { value: 200 }
        ];
        this.list = Object.freeze([
            { value: 100 },
            { value: 200 }
        ]);
    }
})

更多关于 Object.freeze() 的内容可以参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

Share

这周分享一本书《程序员修炼之道--从小工到专家》。 这不是我第一次在博客或者别的地方推荐这本书,如果一定要选一本我最喜欢的书,那我一定会选这本。

这本书是我第一任领导推荐我读的,当时我工作上遇到比较大问题,刚毕业,项目中只有我一个前端,遇到挺多问题,意志比较消沉,也有点闹情绪,当时他推荐我读这本书。现在我依然记得读了第一章第一节那个晚上一整晚没睡好觉,这一节说的是『负责』,对你的代码负责,对你自己和你自己的行为负责。

『负责』多么浅显的道理,却总是被我们遗忘在角落,因为上线时间等情况留下的破窗户,是不是因为没有足够负责。当然,书中也不是让你一味负责死撑,『不要害怕提出要求,也不要害怕承认你需要帮助』。

现在距离我第一次读这本书,已经过去 6 年了,每当工作中非常非常沮丧的时候,就拿出来读一读,也就没那么沮丧了。

刚好今天又遇到很沮丧的事情,拿出来翻一翻,似乎真的没那么沮丧了,希望在明天。


碎碎念

记录一些所思所想,写写科技与人文,写写生活状态,写写读书心得,主要是扯淡和感悟。 欢迎关注,交流。

微信公众号:程序员的诗和远方

公众号ID : MonkeyCoder-Life

程序员的诗和远方