我正在通过雄辩的javascript工作,无论出于什么原因,返回只是在函数nth中不起作用。 老实说,我不明白为什么它不起作用。我知道我非常接近在第n个工作上获得递归版本。这个bug对我来说毫无意义。 以下是所有相关代码:
function arrayToList(array) {
list = null;
for (i = 0; i < array.length; i++ ) {
var x = array[array.length -(i + 1)];
list = {value: x, rest: list};
} return list;
}
function listToArray(list) {
var array = [];
var i = 0;
for (var node = list; node; node = node.rest) {
array[i] = node.value;
i += 1;
}
return array;
}
//return statements are broken here
function nth(list, number) {
if (number == 0) {
//console.log(list.value);
return element;
var element = list.value;
} else if (number > 0) {
list = list.rest;
number--;
//console.log(number);
//console.log(list);
nth(list, number);
} else {
return "Something went wrong";
console.log(number);
}
}
console.log(nth(arrayToList([10, 20, 30]), 1));
任何人都可以解释为什么返回语句在第n个函数中不起作用吗?
答案 0 :(得分:4)
您的代码实际上存在 2 问题 看看小提琴:https://jsfiddle.net/0wpdnn66/
return
function arrayToList(array) {
list = null;
for (i = 0; i < array.length; i++ ) {
var x = array[array.length -(i + 1)];
list = {value: x, rest: list};
} return list;
}
function listToArray(list) {
var array = [];
var i = 0;
for (var node = list; node; node = node.rest) {
array[i] = node.value;
i += 1;
}
return array;
}
//return statements are broken here
function nth(list, number) {
if (number == 0) {
//console.log(list.value);
var element = list.value;// <-- needs to be before return
return element;
} else if (number > 0) {
list = list.rest;
number--;
//console.log(number);
//console.log(list);
return nth(list, number);// <-- needs return
} else {
return "Something went wrong";
console.log(number);
}
}
document.write(nth(arrayToList([10, 20, 30]), 1));
答案 1 :(得分:2)
在为return
分配值之前使用element
,这意味着由于hoisting element
被声明,但是undefined
。
if (number == 0) {
//console.log(list.value);
return element;
var element = list.value;
应该是
if (number == 0) {
//console.log(list.value);
var element = list.value;
return element;
因为我猜你只定义了元素,以便你可以在返回之前记录它,你可以更简单地做到这一点(如Joe Frambach指出的那样)
if (number == 0) {
return list.value;
同样在以下else if
中,它需要返回nth
的通话结果。
这就变成了
} else if (number > 0) {
list = list.rest;
number--;
//console.log(number);
//console.log(list);
return nth(list, number);
答案 2 :(得分:1)
您需要进行两项更改:
function nth(list, number) {
if (number == 0) {
var element = list.value; // <- this goes above the return
return element;
} else if (number > 0) {
list = list.rest;
number--;
return nth(list, number); // <- you need to add a return statement here
} else {
return "Something went wrong";
}
}
有了这个改变:
console.log(nth(arrayToList([10, 20, 30]), 0)); // returns 10
console.log(nth(arrayToList([10, 20, 30]), 1)); // returns 20
console.log(nth(arrayToList([10, 20, 30]), 2)); // returns 30
您基本上是使用递归迭代链表。 number
是您要跳过的节点数。如果number
为0,我们希望返回该值。如果number
为1,我们想跳过一个节点。这就是代码的else if
部分正在做的事情。它正在跳过当前节点,并返回剩余的节点。
要跳转到下一个节点nth(list.rest, --number)
。你不断地这样做,直到数字达到0,这将获得你真正想要的价值。
最终当number
为1时,代码的else if
部分中的return语句将为return nth(list.rest, 0)
,返回您想要的实际值。这就是你返回这个价值的原因。
只是为了好玩,这是一个不使用递归的版本:
function nth(list, number) {
if (number < 0) return;
for (var curr = list; curr && number > 0; number--) {
curr = curr.rest;
}
if (curr) return curr.value;
}
答案 3 :(得分:0)
您可以通过删除var并使用三元表达式来防止这两个问题(在错误的位置声明的var元素和丢失的返回)。这是一种通用的编码风格建议:少var
而少return
=&gt;麻烦少了。
你的功能煮成一个单行:
function nth(list, number) {
return number <= 0 ? list.value : nth(list.rest, number-1);
}
答案 4 :(得分:0)
这样的东西会起作用
function arrayToList(array) {
var list = null;
for (var i = 0; i < array.length; i++) {
var x = array[array.length - (i + 1)];
list = {
value: x,
rest: list
};
}
return list;
}
//return statements are broken here
function nth(list, nr) {
if (nr === 0) {
return list.value;
} else if (nr > 0) {
list = list.rest;
nr--;
return nth(list, nr);
}
}
var list = arrayToList([10, 20, 30]);
var nthNr = nth(list, 1);
console.log(nthNr);
答案 5 :(得分:0)
为了返回“出错的地方”,您需要在访问其属性之前检查MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qRegisterMetaType<qintptr>("qintptr");
m_server = new CustomServer(QHostAddress::LocalHost, 1024, 2, this);
if (!m_server->isReady())
{
qDebug() << "Server could not start!";
delete m_server;
m_server = nullptr;
return;
}
connect(m_server, SIGNAL(clientConnected(qintptr)), this, SLOT(handleNewClient(qintptr)));
connect(m_server, SIGNAL(clientDisconnected(qintptr)), this, SLOT(handleRemovedClient(qintptr)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::closeEvent(QCloseEvent *)
{
if (m_server)
{
delete m_server;
m_server = nullptr;
}
}
void MainWindow::handleNewClient(qintptr id)
{
qDebug() << __FUNCTION__ << id;
m_server->writeData(QString("Hello client id: %0\r\n").arg(id).toLatin1(), id);
m_server->writeData(QString("New client id: %0\r\n").arg(id).toLatin1());
}
void MainWindow::handleRemovedClient(qintptr id)
{
qDebug() << __FUNCTION__ << id;
}
是否为空。实际上,这将检查list
是否未超过其上限,并避免抛出TypeError(如果有)。例如,包括检查number
的下限,
number
在返回语句之前设置function nth(list, number) {
if( number < 0 || !list)
return "Something went wrong";
if (number == 0) {
return list.value;
}
return nth(list.rest, --number);
}
(上面未使用)和从递归调用返回值(如上所述)的问题已在评论和答案中介绍。