最近在做一个面向企业内部生产运输的系统, 生产排程及排车排程算法异常复杂, js 原生容器字典非常简陋, 也缺乏对容器字典进行各种排序过滤反查的手段.
像 java 原生就支持多种集合字典, 不行还有 guava 来凑.
C#的 Linq 就更不用说了.
这几天 js 写的越多就越怀疑人生, 数据处理稍微复杂一点的啥都要自己写工具函数来干, 是不是我水平太菜了, 实际 js 是有简单现成的进行复杂的数据处理的办法的?
1
libook 2022-07-28 11:39:41 +08:00 7
对 Java 不大了解,可以详细讲一下“容器字典”、“集合字典”是什么概念嘛?
处理一组数据的话,通常 JS 里可以使用 Array 、Map 、Set ,特殊需求下可以自己构造数据结构和自建迭代器。 建议不要用一种技术栈的思维硬套在另一种技术栈上,比如你完全用 Java 的思想来写 C#也一定很难受,既然要用 JS 就最好按照 JS 的思维来设计程序。 所以可以把具体问题发出来,V 站里不缺精通 JS 的人,大家可以帮你看看究竟是 JS 不合适这种需求还是有你不了解的更好的方案。 |
2
nowheremanx 2022-07-28 11:41:39 +08:00
|
3
AaronWang13 2022-07-28 11:49:05 +08:00 2
js 作为编程语言来说本身就是有残缺的,因为他原来就是个脚本语言,运行环境也仅仅是在浏览器环境。
|
4
AoEiuV020CN 2022-07-28 11:50:35 +08:00
我感觉 javascript 处理数据最糟糕的是处理二进制数据,
关键不同的第三方库都是分别封装自己专用的字节数组, 有些情况实在没办法甚至只能序列化再反序列化来传递参数, 不过我不是专业 js 的,不怎么确定, |
5
TWorldIsNButThis 2022-07-28 11:50:53 +08:00 via iPhone
js 标准库是残废的 要自己引数据结构的包
|
6
AaronWang13 2022-07-28 11:52:58 +08:00 2
但是 js 生态繁荣啊,这么多年修修修补补,写后台逻辑还是够的,建议你多去看看社区现有的轮子,比自己硬干好。
|
7
bthulu OP @libook 比如有界 /无界队列, 阻塞 /非阻塞队列, 有序集合, 按对象指定属性判重的集合, 双向字典, 多 key 字典, 字典集合原生支持 getOrAdd(或 Compute)之类的操作, 字典按某个字段分组(类似 SQL 里的 group by), 集合依次按对象多个属性进行排序,...
|
8
bthulu OP @AaronWang13 能伸手问下, 有哪些现成的轮子吗
|
9
libook 2022-07-28 12:00:49 +08:00
JS/ES 是个一直在快速迭代发展的语言,到现在依然每个月都有新的草案被提出或正式被引擎支持,其实已经有相当多的新特性可以给开发提供各种便利了,只不过很多人不知道罢了。
如果对 JS 的印象还停留在在几年之前,已然今非昔比。 |
10
ljpCN 2022-07-28 12:03:09 +08:00 2
@bthulu #8 楼上已经有朋友说了 lodash ,另外推荐一个 ramda 。你在 7 楼提到的 groupBy 这种操作这些工具库是有的。队列与栈在 JS 里都是数组的原生操作就支持,不过要实现你说的有界 /无界种种限制,可能要借助第三方库,善用 npm 即可。
|
11
mxT52CRuqR6o5 2022-07-28 12:03:29 +08:00 via Android
|
12
Pythoner666666 2022-07-28 12:12:01 +08:00 2
看了楼上的回答,nodejs 在国内不火倒是有原因的。
|
13
Pythoner666666 2022-07-28 12:13:32 +08:00 2
@libook 确实如此,我在知乎上提到 nodejs 的语言的一些优势,一堆人来喷我。。。他们摆出的一些观念和语言特性,基本上还停留在 0.X 的版本
|
14
molvqingtai 2022-07-28 12:16:44 +08:00 1
如果还是使用的的 ES5 的话,那么处理数据确实比较麻烦,建议使用 ES2020+
比如分组,自带的就有 Array.prototype.group() (可能需要 polyfill ),还有 Map Set 这些完全够用了 再不够,直接用 lodash |
15
duke807 2022-07-28 12:17:08 +08:00 via Android
沒錯,後台還是用 python 更方便
|
16
codehz 2022-07-28 12:20:19 +08:00
js 的最大缺陷大概就是没有(支持直接共享内存的)原生线程吧,worker 的线程其实也可以用一些同步原语(包括原子操作和锁定语义),SharedArrayBuffer 也不是没有——但是只能操作二进制数据,不能直接用来传递对象——因而进行相关封装的就比较少(所谓阻塞队列,基本也是在多线程语境下才有意义吧),这也是为什么明明 wasm 性能不一定比 js 好,但是仍然有很多用到多线程处理的库采用 wasm 进行(
不过对于简单的多线程处理,采用 postMessage 的方法也不是完全不能接受,太重的计算就不太适合了 |
17
thinkershare 2022-07-28 12:27:28 +08:00
你说的这些和 ES 这门语言没啥关系. ES 的标准库太弱了, 前端看上去如此繁荣的主要原因就是因为标准库太弱, 而 JS 要做的事情又越来越多, 因此大家不停的造出来各种轮子, 然后有了 npm 这种辣鸡, 然后不停的玩废掉一个个框架, 再来创建一个新的. 核心原因就是标准库太弱了, 随便实现点什么功能都要引用一大堆第三方 library, 而且很多 Library 就几行代码, 你根本不知道整个 npm 按照的依赖都是些什么鬼东西.
|
18
mxT52CRuqR6o5 2022-07-28 12:31:08 +08:00 4
js 毕竟客户端语言,不应该设计出很重的标准库,用 js 就要习惯于去找社区实现的轮子
|
19
blindie 2022-07-28 12:34:31 +08:00 2
有界 /无界:数据流 Stream 吗?用的不太多,其他人可以补充。
阻塞 /非阻塞:Promise | async await 去重 /不去重队列:去重可用 Set ,不去重 Array Map 都可 有序集合:Array Map 自带顺序 按对象指定属性或函数判重的集合:ArrayLike.filter() 双向字典:用两个 set 多 key 字典:add, search 用 set 就可以,delete 可以用双向字典实现 (这个可能稍微复杂一点) 字典集合原生支持 getOrAdd(或 Compute)之类的操作:Array.map() 字典按某个字段分组(类似 SQL 里的 group by):仅查询时候用 ArrayLike.filter() 就可以。如果要优化查询速度直接 Set 包 Array 就可以 new Set<ArrayLike>。 集合依次按对象多个属性进行排序:Array.sort() 你的这些基本上都可以用 ES6 的数据结构加上他们的方法快速实现掉,甚至都没有用上 lodash 。如果是语法角度的话,JS (ES6) TS 是非常 ducktyping 的,不需要先定义是什么数据结构而是通过函数链式组合来实现功能。 |
20
adoal 2022-07-28 12:38:39 +08:00
JS 圈连 left padding 这种一句话的事都要专门写一个包。据说凡是能用 JS 重写的都会用 JS 重写(另一个有此殊荣的语言是 Rust )。你想做的事,社区都有包,只是包的质量不一定靠谱罢了。
|
22
dcsuibian 2022-07-28 12:50:56 +08:00
@bthulu 你说的这些 js 基础库确实没有啥支持的,正常一下子也用不到那么多。
不过基本的排序过滤反查其实都是有的,稍微多一点代码也都能实现。 js 中基础的数据结构是不缺的,数组其实就是变长数组,也支持 push()、pop()、shift(),基本就是有队列、栈的功能。 ES6 有 Set 、Map ,而且支持按插入顺序遍历,甚至对象本身其实也能做一个 Map 。 |
23
xingjue 2022-07-28 12:58:25 +08:00
go 不香吗
|
24
Rache1 2022-07-28 13:02:52 +08:00
@libook 这个出现的也有些晚了,在 ES 2017 里面出现的(常说的 ES 6 指 ES 2015 ),当然,现在大部分情况下都是可用的了 😆
|
25
adoal 2022-07-28 13:09:09 +08:00
@libook 历史上著名的 azer left-pad 包血案……事后还有人做了一个段子包 is-thirteen 来调侃 JS 圈封包太小太细的现状
|
26
xg4 2022-07-28 13:18:58 +08:00
|
27
xg4 2022-07-28 13:24:32 +08:00
uniqBy
|
28
Mexion 2022-07-28 13:45:45 +08:00 2
@xingjue 你仿佛在搞笑,go 也配和 js 比,还是在数据操作方面,就 go 这种啥都没有的语言,都不够给其他语言提鞋,垃圾中的垃圾
|
29
zhuangzhuang1988 2022-07-28 13:54:58 +08:00
@bthulu 很多前端不知道这些的,java C#里标准容器很多宝库的 js 是没有的
|
30
dcsuibian 2022-07-28 13:54:59 +08:00 7
我 js 和 Java 都写,C#不写。个人也觉得 js 写后台不好,但也没那么差,主要是要:扬长避短。
js 写起来比较舒服的点: 1 、函数式支持。数组可以直接使用 map 、reduce 、filter ,Java 这边就得先弄成 Stream 搞流式编程。 2 、如果要创建一个对象,不必特定搞一个类。直接双花括号就可以。 3 、语法糖。js 的语法糖很多,比如正则表达式、模板字符串、解构赋值等,处理 JSON 更是极其方便。 4 、没有 Java 那个检查型异常,写起来方便很多。 5 、异步支持。js 有 promise 、async/await 。由于自身单线程的特性,对异步的支持非常好。 但缺点: 1 、不严谨。js 本身有很多设计缺陷,比如 falsy 、undefined 还有各种离谱的隐式转换等等,不熟悉的话容易踩坑,考验你和同事的水平。 2 、性能,js 主要考虑功能,很少考虑实现。比如 ES6 的 Set 就是直接 const set=new Set()。数组当队列也是,能用就行。 3 、单线程事件循环模型,比如你的阻塞队列就是没有的。 能拿来写后台的一个很大原因是不少后台都是 IO 密集型而非计算密集型。而 JS 是把网络 IO 交给底层去管,所以轻松。要是计算密集型估计就蛋疼了。 4 、工具差。官方模块化基本是 ES6 的事了,导致要考虑 CommonJS 、ES Module 、AMD 啥的。npm 设计也是稀烂,包管理器都能吵起来。 5 、生态差,缺乏最佳实践。隔壁 Spring 开发 web 后台,大体都给你定好了,直接用就行。 另外非常赞同#1 的观点,不要用 Java 的思想写 JS ,比如: 1 、Java 有类。比如 toString()、hashCode()、equals()方法你可以直接改类。但 JS 如果你用花括号定义的对象其实是直接来自 Object 的,个人觉得改 Object.prototype 应该不是个好主意。 2 、Java 有类,有注解,有反射机制。比如 JPA ORM 就靠反射获取信息,但 JS 的肯定就不是这么做了。 3 、 @Transactional 注解。既有注解,又是线程相关的模型。 4 、Java 强制你用面向对象的语法写,但 js 没有。 |
31
libook 2022-07-28 14:10:06 +08:00 1
看了题主的附言,也能够理解题主的困惑,JS 目前不包含很多现成的复杂数据结构,但是繁荣的技术栈生态使得总能够找到第三方的实现,而且可以找到多家实现进行 PK ,如果一种实现被大多开发者接受,那么也有可能以草案的形式逐渐成为 JS/ES 标准的一部分,算是某种市场化发展理念吧。
所以客观来说,题主附言里的大多东西 JS 标准 API 里是没有的,大量涉及这些数据结构和算法的场景就需要第三方库或自建库来实现了。 我做过 7 年的 JS 后端开发,但确实日常业务中涉及队列的情况比较少,要么就是分布式微服务架构下使用 Redis 、RabbitMQ 之类的消息队列中间件,要么就是自己简单手写个队列(比如流控、时序和削峰填谷),所以暂时也无法推荐什么好用的库,我只说一些自己实现的思路吧。 单纯的先进先出的话,Array 有现成的 push 、pop 、shift 、unshift 等方法可以用,取决于你是想按索引正序还是倒序排队。 有界无界这个没有原生 API ,如果需要的话我通常是把 Array 封装成一个对象,然后在 add 的时候自己加个数量判断。 JS 使用 promise 及其语法糖控制异步过程,阻塞可以在 add 或 remove 的时候判断队列状态,需要阻塞就暂时不 resolve promise 。 去重可以内置 Set 或 Map ,也可以在封装的 add 方法中自己定义复杂重复判定过程。 有序集合可以用 Map 或 Object ,无序集合可以用 Array 、Set 。 双向字典和多 Key 字典可以用多个个 Map 或 Object 封装一下。 getOrAdd 可以在 Map 、Object 、Set 基础上封装。 分组和排序可以用 lodash 之类的工具库,sort 很多时候手写个 callback 也挺方便的。 如果频繁使用这些数据结构的话,可以自己写个 library ,然后在各个项目中引用。 |
32
IvanLi127 2022-07-28 14:13:01 +08:00
JS 的内置库确实没 JAVA 和 C# 丰富,不过解释型的语言倒不拘泥这块,用是没问题的,正常开发也感受不到相比其他语言有什么明显缺陷。复杂的数据处理之类的,应该去引用第三方的库,一般都有很成熟、热门且好用的开源库给你选。
数据集合操作我推荐引用 ramba.js ,FP 爽呀 另外,JS 和 JAVA 、C# 思想还是有些不同,有些东西不能类比 |
33
guanhui07 2022-07-28 14:18:16 +08:00
https://github.com/ecrmnn/collect.js 这个 collect.js 觉得 挺好用的
|
34
ipwx 2022-07-28 14:18:25 +08:00
说得好,我选择前端用 js ,后端用其他语言。
|
35
ChevalierLxc 2022-07-28 14:44:03 +08:00
总感觉题主是没有人带着做 JS 项目,自己撸出的问题。。
|
37
byzf 2022-07-28 15:11:48 +08:00 14
错误的提问方式:
求推荐 javascript 处理集合的基础库。 回复:2 收藏:16 正确的提问方式: js 先天残缺,没有处理集合基础库。 回复:100+ 收藏:0 |
38
ScepterZ 2022-07-28 15:14:22 +08:00
go 也很缺这些,个人觉得对开发效率和 bug 率都挺有影响的
|
39
zhuangzhuang1988 2022-07-28 15:14:54 +08:00 2
|
40
hahasong 2022-07-28 15:16:01 +08:00
lodash 了解一下,js 基础库是简漏了点,但奈不住包多 屁大个方法都有对应的包
|
42
banricho 2022-07-28 15:24:49 +08:00
我觉得主要还是人的问题
|
43
FallenMax 2022-07-28 15:57:27 +08:00
前后端都用 js ,有一些非常方便的特性:
0. 前后端可共用一些基础业务类型 /工具,代码一致性高 1. 前后端通讯不需要定义 http 接口,实现一个简单的 rpc 就可以像调用方法一样调用后端 API ,并且类型安全 2. 设施准备良好后,项目启动快,改动前后端代码都触发浏览器刷新,生产力之选 |
44
forgottencoast 2022-07-28 16:04:42 +08:00
|
45
lbunderway 2022-07-28 16:10:29 +08:00
觉着是楼主自己不知道
|
46
BUHeF254Lpd1MH06 2022-07-28 16:17:13 +08:00
开惯了特斯拉在开三缸手动挡,当然会觉得先天残缺
|
49
DingJZ 2022-07-28 17:15:52 +08:00
在现阶段,我国社会的主要矛盾是人民日益增长的物质文化需要同落后的社会生产力之间的矛盾。
|
50
jamosLi 2022-07-28 17:44:47 +08:00
首先需要说明的是 js 有很多版本,其次要说明的是 js 本身只是一个脚本语言,从出生到现在用的比较多的是在前端领域。在后端的应用也是在 node 出来以后。你提的一堆数据结构,或者业务场景即便在 java 中也不是一开始就有的吧。你拉着一个英国人问他你是不是天生在说中文上有缺陷,这是不是有点扯,一切都是在进步的。一个复杂的系统要想追求机制的性能,很难一套语言一把梭。并且类似于 java94 年出来,到现在生态已经非常繁荣,js 搞后端也要从 node 出来的 09 年算,并且生产应用规模还不是很大。总之这么一个提问非常没有意义。虽然 java 又臭又长,但是最好还是能把 js 慢慢改成 ts 。
|
51
guxin0123 2022-07-28 19:08:32 +08:00
js 也有 linq 插件可以用
|
52
urnoob 2022-07-28 21:24:26 +08:00 via Android
就算用 js 写好了 后期维护你自己都看不懂当初的代码。js 只适合拿来写页面
|
53
iikebug 2022-07-28 21:48:46 +08:00 1
@zhuangzhuang1988 js-sdsl 一个参考 C++ STL 实现的 JavaScript 标准数据结构库,你是说这种数据结构嘛?
|
54
hangbale 2022-07-28 21:59:51 +08:00
每种语言设计之初都有明确的方向和目的
js 被设计成浏览器里运行的语言,它的特性严重依赖各大浏览器厂商的支持程度,而且各家实现方案还不一样 曾经浏览器兼容性问题频频出现在前端面试中,就很搞笑 即便如今 NodeJS 流行开来,也是得益于 JS 开发者多,门槛低,底下用 C*糊了个 V8 和 libuv 获得了不错的性能。 JS 的特性也越来越多,可惜大部分用不到,专业的场景也有比它更好的语言 就像我花 50W 改装一台思域 Type R ,看起来不错,0 百加速甚至媲美超跑,但是呢,上了赛道被 911 吊打,去夜店被兰博基尼吊打,只有红绿灯起步的瞬间能让大家另眼相看 |
56
zhuangzhuang1988 2022-07-28 22:46:41 +08:00
|
57
CptDoraemon 2022-07-28 23:41:27 +08:00
害,日子不还得过吗
咱 leetcode 周赛都拿 js 来写,一个 heap 我在那糊了 20 分钟 别人引个库两行完事了 😭 |
58
wxlwsy 2022-07-29 00:10:24 +08:00
一时写一时爽,写多了就是火葬场. 任何弱类型动态语言都"不太适"合写"复杂业务"的后台.
|
59
dayeye2006199 2022-07-29 00:44:40 +08:00 via Android
我做过很多类似 lz 这样的需求。首先拿 js 写这样的重计算需求是不太合适的,一是数据结构孱弱,二是缺乏这类算法的轮子。
常见的做法是用 Cpp 或者 py 配合 https://developers.google.com/optimization 这样的轮子搓一个封装好的函数出来。 然后用 RPC 或者消息队列这样的语言中性的方法暴露接口出来,取决于是需要同步或者异步调用。 前端再调用这样的服务。 |
60
DeWjjj 2022-07-29 00:44:47 +08:00
可它真的包多...
他是世界上包最多的... |
61
bxb100 2022-07-29 00:59:43 +08:00
歪个楼,请问生产排程及排车排程算法有啥资料可以看吗,一直挺好奇这个实现的
|
64
Felldeadbird 2022-07-29 10:49:41 +08:00
JS 没有太多标准库啊。很多东西你不是搞前端的,用后端思想去写就会觉得特别难受。很多后端有的 JS 自身没有。而且 JS 还要考虑国产壳牌浏览器的兼容。。。过于新的语法,你还要引入兼容库。
nodejs 不太清楚,毕竟我没深入写过。 |
65
seenthewind 2022-07-29 11:10:31 +08:00 1
我只能说,你差不多快看到本质了。
如果学编程的人够早,就知道以前的语言是什么样,javascrip 刚出来的时候是什么样。 用 C++的人喜欢说一句话,一个东西一旦好用,那么很容易被滥用,很多语言的维护团队都在极力发扬好用的一面,克服滥用的一面。 JS 派系除外。 我不止一次被 js 开源项目那恐怖的依赖关系恶心到,如果你有幸遇到报错,可以看看究竟抛出了多少东西(我基本上像是看到了一个宇宙级 Exception )。 至于后面的各种封装、库、什么社区、什么前人的轮子,我的理解是,当你造汽车时有一百个轮子可以选,就基本相当于没得选,而且选个轮子耗时,自己写一个轮子也耗时。 于是他们决定用轮子自动造轮子,真的是牛逼至极。 |
66
zw1one 2022-07-29 15:54:47 +08:00
node.js ?
|
67
humbass 2022-07-29 18:42:06 +08:00
@bthulu 2015 年就已经实现很多常用的操作
针对 Array 的操作 filter\map\every\some , 以及 set 、weakset 、map 、weakmap 相关,都相当好用 在 es6 标准出来之前,相当多应用使用 underscorejs 来执行上诉功能 |
69
Mexion 2022-07-30 03:33:04 +08:00 via iPhone
@zzhzero gop 经典的胡言乱语,k8s 再 nb 又能证明什么,能证明 go 不简陋吗?何况 k8s 是 google 选择用 go 写而不是只有 go 能写。其次我还真没用 k8s 。
|
74
Mexion 2022-08-02 23:45:32 +08:00 via iPhone
@zzhzero 你真是纯纯的🤡,不用 k8s 就是 low 就是视角有限,我目前专注于前端,k8s 又不属于我的领域上不上关我鸟事,这种自我感觉优越的逆天言论也只有 go 孝子这种群体能够这么大言不惭地说出来
|
75
fanyer 2022-08-08 02:09:39 +08:00
@qrobot 你怕是不知道 7 年前 npm 怎么设计的,锁版本有 p 用,当时库里就是即时删的,没经历过那个环境就别 bb
|
76
qrobot 2022-08-08 10:48:49 +08:00
@fanyer #75
你说的 7 年前也就是 npm 3.8.5 是七年前最后一个发布的版本, 因为之后的 3.8.6 是 6 年前发布的, 如果你没说谎, npm 的版本就是 3.8.5 来让我们看看日志啊 你也可以自己打开看 npm-shrinkwrap(1) -- Lock down dependency versions 怕你英语不好, 我帮你翻译下 npm-shrinkwrap(1) -- 锁定依赖版本 - https://github.com/npm/npm/blob/v3.8.5/doc/cli/npm-shrinkwrap.md 人不行,就怪环境不行? 就算没有 lock , 操作 `node_modules` 写个 lock 难道很难? 而且 npm 本身就提供了 npm-shrinkwrap 给你锁版本。 至于你说的第二个问题, 库是即时删除的。verdaccio 7 年前就提供 1.4.0 版本的 npm 私服。 - https://github.com/verdaccio/verdaccio/tree/v1.4.0 我没有 bb, 七年前就方案了。 请问你怎么会觉得没有用? 还是说你连这个都不知道? 人不行,就怪路不平? 水平差就怪 npm 不好用, 设计的有问题? facebook 觉得 npm 设计不符合他们的想法, 所以做了 yarn, pnpm 觉得 npm 太占磁盘了,所以重写了, 而你做了什么? 除了抱怨以外,哪怕是给别人提一个 issuse 的事情你做了吗? 你不会,就多问问别人,向别人虚心请教 |
77
zzhzero 2022-08-19 22:23:04 +08:00
@Mexion 有这么多时间喷人不如去调查一下大公司标准的前端业务上线流程,真的是什么都不知道 bb 个没完了,没长脑子就别说话。
|