[培训向]如何给学员讲明白一种算法不合适?

2019-01-31 11:06:52 +08:00
 libook

直奔主题吧,楼主是做 Node.js 的,培训实习生的时候有一个实习生写了这么个算法:

/**
 * 将任意类型元素的数组转化成字符串数组
 * @param {Array} theArray
 * @returns {String[]}
 */
function toStringArray(theArray) {
    if (theArray.length > 0) {
        return theArray
            .toString()//将数组整个转化成字符串,如[1,2]在 toString 之后会变成'1,2'
            .split(',');//将上面返回的字符串,以','为分界分割成字符串数组
    } else {
        /**
         * 如果数组的长度为 0,没必要做任何处理,则直接返回原数组
         */
        return theArray;
    }
}

考虑到这个频道里可能有些朋友不是很熟悉 JavaScript,所以我优化了一下写法,并增加了一些注释,希望尽可能讲明白这个算法思想是什么。

通常肯定是循环处理数组中每个元素,然后每个元素转成字符串,最终生成一个新数组。 直观上觉得学员的算法不妥,但一时又无法从脑海深处挖掘出究竟问题出在哪,觉得直接向学员宣判这种为错误算法也不好,最好让他能知其所以然。

故在此抛砖引玉,请有想法的朋友各抒己见。

3063 次点击
所在节点    程序员
13 条回复
Allianzcortex
2019-01-31 11:10:06 +08:00
可以问输入的元素中包含分隔符怎么办?
Allianzcortex
2019-01-31 11:13:04 +08:00
之前遇到过这种情况,找了下:

[日志打码用的是 pageName&{key1:value1,key2:value2} 的形式,通常情况下用 split(“&”)[1] 得到 JSON 字符串后用 get_json_object 来查就可以了。但如果所提供的 value 里面有多个 “&”(如含参的 url),那么分隔开后就会产生只有一个 " 的字符串,读不出 JSON 格式。所以就写了一个 UDF 来解决(]
libook
2019-01-31 11:13:13 +08:00
@Allianzcortex 好主意,这种算法会限制输入的数组当中任何一个元素转换成字符串后都不得出现逗号。
sherryqueen
2019-01-31 11:13:57 +08:00
对象怎么办, 字符串怎么办. theArray 为 null 或 undefind 怎么办. 可以考虑下多种类型下的问题. 因为注释上写着是任意类型
wenzhoou
2019-01-31 11:18:00 +08:00
抛开具体的场景说算法那就是耍流氓。

你可以问问他,他的这种方法适用于那些场景,不适用于哪些场景。这属于一种拓展思维训练。

没有好和不好,只有适用和不适用。

不然你说人家的不对,你能找个对的出来吗?
libook
2019-01-31 11:18:20 +08:00
@sherryqueen 你说的问题确实存在,输入没有做必要的校验,以及对于数组中元素的类型是否需要分类处理。
Vegetable
2019-01-31 11:18:43 +08:00
时间复杂度和空间复杂度都更高,无法用其他语言实现,所以算是一个 trick.这么写没问题,但是一点不扎实,可读性差,并不是所有人都知道[1,2.3].toString()=="1,2,3"等等,槽点很多但是都不是很致命,综合到一起就是烂代码.
libook
2019-01-31 11:23:49 +08:00
@Vegetable 恩,之前想到了算法复杂度的问题,可读性这块确实是值得注意的。
TomVista
2019-01-31 11:25:32 +08:00
用 es6 耍流氓.
TomVista
2019-01-31 11:26:23 +08:00
#9 删掉 ,抱歉
cppgohan
2019-01-31 11:51:44 +08:00
大龄程序员, 业余 JS 菜鸟, 说几点, 欢迎交流:

1. 学员写的这个 split 操作, 我觉得挺取巧的. 感觉没大毛病, 如果返回预期, 真的就是把任意元素每个 toString 一下, 面对 null, 或者 undefined 的处理逻辑, 也借助[].toString 的行为来变成空了. 感觉如果这和要求的输入输出一致, 感觉也不会啥问题. 唯一不妥可能是执行会多出来一个拼字符串和拆字符串的消耗.

2. else 的实现, 我觉得是个 bug, 不应该直接返回参数本身, 应该返回一个新的[]

3. 函数入参可能要做下非空检查?
no1xsyzy
2019-01-31 12:04:10 +08:00
theArray 是 Array of _ ?
简单举个反例好了,toStringArray( [1,[1,2],2] )
这下连数组长度都不一样了
另外,我的习惯是每个元素转化为字符串的方式我觉得也作为参数传入会比较好
然后你就会发现这是个 map
XD
libook
2019-01-31 12:24:39 +08:00
@cppgohan 感谢分享。

split 确实凑巧在处理 null 和 undefined 上面提供了一些便利。
返回的话也确实存在两种情况表现不一致的问题,要么就全返回原数组,修改也在原数组上修改,要么就全返回新数组,只要统一一种模式并在文档中写明就好多了。
入参检测是要注意,也相对比较容易讲明白。

@no1xsyzy 我其实就是跟他说让他去看 map😂。你举的反例一针见血。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/532083

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX