设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 3885|回复: 21
打印 上一主题 下一主题

[有事请教] 为什么push进去都是undifineied

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

跳转到指定楼层
1
发表于 2020-9-22 00:01:47 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 kklt 于 2020-9-23 11:04 编辑

JAVASCRIPT 代码复制
  1. var runningSum = function (nums, list = [], i = 0, ) {
  2.     if (i == 0) {
  3.         list.push(nums[i])
  4.         runningSum(nums, list, i+=1)
  5.     } else {
  6.  
  7.         list.push(george(nums,i) )
  8.         if (i == nums.length) {
  9.             return list
  10.         }
  11.     }
  12.     runningSum(nums, list, i+=1)
  13.  
  14.  
  15. };
  16. function george(nums,i,sum = 0,b = i) {
  17.  
  18.     if (b == 0) {
  19.         return sum
  20.     }
  21.     if (b < nums.length){
  22.         sum += nums[i-=1]
  23.     }
  24.     george(nums,i,sum)
  25. }
  26. var temp = runningSum([1, 2, 3, 4, 5])
  27. console.log(temp)



我想实现一个数组和的实现,就是接受一个数组,返回一个每项都是前所有项的和的数组。
但是为什么当我把george()push进list确是undifined。
take is cheap

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

2
 楼主| 发表于 2020-9-22 00:13:58 | 显示全部楼层

第19行那个return sum 不能吗
take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

3
 楼主| 发表于 2020-9-22 00:18:44 | 显示全部楼层
喵呜喵5 发表于 2020-9-22 00:12
第24行,你倒是return啊


有点不太懂。。
那个。return sum 难道不是就是把sum返回然后终止函数吗。
为什么后面还要return george。
take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

4
 楼主| 发表于 2020-9-22 01:35:20 | 显示全部楼层
喵呜喵5 发表于 2020-9-22 00:38
因为你在 george (b != 0) 里面又执行了一个 george (b == 0),
return sum 结束了 george (b == 0),但 ...

感谢。
就是说sum其实是被return到了上层的grogre,
除了b==1的geogre,
其他geogre都没有返回值,
所以是undifined。

改了一下,这样就行了。
  1. var runningSum = function (nums, list = [], i = 0, ) {
  2.     if (i == 0) {
  3.         return runningSum(nums, list, i += 1)
  4.     } else {
  5.         console.log('up' + i)
  6.         list.push(george(nums, i))

  7.         if (i == nums.length) {
  8.             return list
  9.         }
  10.     }
  11.     console.log('down' + i)
  12.     return runningSum(nums, list, i += 1)

  13. };

  14. function george(nums, ig, sum = 0, b = ig) {

  15.     if (b == 0) {
  16.         return sum
  17.     }
  18.     if (b <= nums.length) {
  19.         sum += nums[ig -= 1]
  20.         return george(nums, ig, sum)
  21.     }

  22. }
  23. var temp = runningSum([1, 2])
  24. console.log(temp)
复制代码
take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

5
 楼主| 发表于 2020-9-22 01:43:30 | 显示全部楼层
SixRC 发表于 2020-9-22 01:13
你在学js吧..感觉各种东西都有 代码写的比较神奇
js中假如不指定返回值就会返回undefined
举一个很简单的例 ...


啊哈,编辑的时候没看见你的回复。
(要是早点刷新就好了,省了我自己一个人大半天功夫。)
总之多谢啦。
我的确在学js,和《sicp》同时在学,里面用的是lisp(以前也学过一些ruby)
就和你说的一样,我把它们混淆在一起了。。
现在算是清楚了。
take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

6
 楼主| 发表于 2020-9-26 21:52:14 | 显示全部楼层
本帖最后由 kklt 于 2020-9-26 21:56 编辑
SixRC 发表于 2020-9-22 01:13
你在学js吧..感觉各种东西都有 代码写的比较神奇
js中假如不指定返回值就会返回undefined
举一个很简单的例 ...


确实。
递归模拟循环。
其实,我这么写也是因为产生过的以下想法:
如果递归循环看作操作符”jump“的一种,那它们似乎就那样没太大差别了。

你说的”写在一起或单独写出来"(但愿没有理解错‘我头疼了’的含义)
就我所知道的知识,我可以拿来谈一谈。

在lisp中foreach这样定义(感觉js应该也差不多)。
写成js的话大概是这样。
(浆糊代码。如果有更好的模拟方法,欢迎碾压。
本来想写一个对于数组的类似cdr car,结果写出来感觉不太好。那就手工实现一个cons吧。
如果不太了解这些lisp的词汇,看了下面的代码就应该知道了)

JAVASCRIPT 代码复制
  1. //=============================================================================
  2. //js 模拟 cons  使用array版本(lisp有单项链表list,写法是用()包起来的一组数。用array主要是想在语法上能和lisp有点衔接,既用array来表示list)
  3. //=============================================================================
  4. let Cons = function (left=‘undefined’, right = 'undfined') {
  5.     this.car = left;
  6.     this.cdr = right;
  7. }
  8.  
  9.  
  10. function itemToCons(array) {
  11.     //let ineerarray = array.slice(0);
  12.     array.forEach((v,i,a) => {
  13.         a[i] = new Cons(a[i]);
  14.     });
  15.     return array;
  16.  
  17. }
  18.  
  19. function combineCons(array) {
  20.     //let ineerarray = array.slice(0)
  21.     array.forEach((v,i,a) => {
  22.         if (i <= a.length - 1 -1  ){
  23.             a[a.length - i-1-1].cdr = a[a.length - i-1]
  24.         }
  25.     });
  26. }
  27.  
  28.  
  29. function arrayToCons(array) {
  30.     combineCons(itemToCons(array))
  31.     return array
  32. }
  33.  
  34. function getlist(array) {
  35.     if (array[0]){
  36.         return array[0]
  37.     }else return array;
  38. }
  39. //foreach
  40. function fooeach(something, f) {
  41.  
  42.         if (!getlist(something).cdr){
  43.             return
  44.         }
  45.         getlist(something).car = f(getlist(something).car)
  46.         return fooeach(getlist(something).cdr,f)
  47.  
  48. }
  49. asd = [1,2,3,4,5]
  50.  
  51. fooeach(arrayToCons(asd), function (i) {return i*2})
  52. console.log(asd)


就如上所述。
foreach和之前写的那串合在一起的代码。
它们相同点地方都是:获取 ’‘ 数组 ’‘ 信息+条件判断+jump。
如果把runsum抽象出来,再给它的参数列表里加上回调函数,就是foreach。
george就是传入的回调。







take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

7
 楼主| 发表于 2020-9-27 11:37:48 | 显示全部楼层
本帖最后由 kklt 于 2020-9-27 13:27 编辑
SixRC 发表于 2020-9-22 01:13
你在学js吧..感觉各种东西都有 代码写的比较神奇
js中假如不指定返回值就会返回undefined
举一个很简单的例 ...


抱歉,我没有讲清楚。
我为什么说循环和递归差别不大呢?看这里。(伪代码)
这里变量就都当作传引用的把。

用jump写的循环。
a = 1
:asd
a++
jump :asd

这里就是不断循环执行a++。

现在这样写.
a=1
func(num){
    num++
   func(num);
}
func(a)

效果相同。
不同点(Maybe)
循环应该是一种单一的过程。
在执行过程,数据不断执行这些过程,内存上不会有太大变化。
也就是jump到循环开始。如果有终止条件的话就直接jump出来。

递归的话,一是保存外层函数的环境,一是不断在创建的函数环境创建函数环境。所以内存占用也会更多。
也就是jump到新创建的函数体。如果有返回的话最终逐函数jump出来
然后我这样写。


a=1
b=0
:asd
if a/2==0 a++
jump :bsd
jump :asd
:bsd
b+=a
jump :asd

跳转的:bsd,是不是像像进入一个新环境?
是不是看起来越来越像递归?
对比下面:

a=1
b=0
func (num){

  if (a/2==0)  func(a++)
   b+num
}
func(a)

所以我说,循环递归都是jump。
都是有限制的jump。
有限制的jump虽然降低了灵活性,但却提升了可靠性。
take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

8
 楼主| 发表于 2020-9-27 15:26:26 | 显示全部楼层
本帖最后由 kklt 于 2020-9-27 15:28 编辑
SixRC 发表于 2020-9-27 14:27
递归本质并不是jump 而是call和ret
所以递归天然的保存了每一帧的信息
这是它和循环最大的不同


其实我觉得你说的很到点。

虽然说我这里的jump不是特指汇编里面的jump。
屑特,好吧还是我没讲清楚。
我这里这个jump,
一定要说是属于那里的话:
是来自一款指令式的程序小游戏 human resource manager,
其中不存在call,ret,也没有函数。所以里面的循环都是用jump来实现的
对于汇编,我虽然知道一些,但在你说出call和ret之前我甚至都不知道它们的存在。
我说的jump大概更像是一种组件。将它和一些代码组合,可以实现任何存在重复的问题(甚至以外的问题)
对,因为代码很多时候看起来就像是在跳转,这个跳转的就是我说的jump。
好吧,这确实有点想当然了。
也许可以用jump来写一个不同的版本。

点评

不同的环境给的积木不同 所以没必要必须找到相同的积木去搭 合适的就是最好的 是我一直想表达的意思  发表于 2020-9-27 15:51
call和ret也是组件呀 任何代码块都是 假如把不同功能的组件当作积木 编程不就是搭积木吗 积木的搭法就是编程的范式  发表于 2020-9-27 15:49
take is cheap
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

9
 楼主| 发表于 2020-9-27 17:06:53 | 显示全部楼层
本帖最后由 kklt 于 2020-9-27 17:41 编辑
SixRC 发表于 2020-9-27 14:27
递归本质并不是jump 而是call和ret
所以递归天然的保存了每一帧的信息
这是它和循环最大的不同

不同的环境给的积木不同 所以没必要必须找到相同的积木去搭 合适的就是最好的 是我一直想表达的意思


yes,yes
我get了。

之前用js仿lisp,是考虑到可能读者不了解lisp。同时也是顺便借机尝试一下这个想法。

我说的jump大概更像是一种组件。将它和一些代码组合,可以实现任何存在重复的问题(甚至以外的问题)


妈淡,果然发言还是要在斟酌一下。
其实这句话,更偏向于指jump的泛用性。。
原话确实读起来会有点模糊。

点评

恩 理解 (我也就是随口一说 吧)  发表于 2020-9-27 17:21
take is cheap
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-3 01:16

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表