使用if语句的条件作为返回值

huangapple go评论68阅读模式
英文:

Use condition of if statement as return value

问题

I have a function that returns either false or a number other than 0. Now I'm calling this function in another function to conditionally return the number.

function falseOrNumber() { ... }

function otherFunction() {
    // ...
    if (falseOrNumber()) return falseOrNumber()
    // ...
}

Now I was wondering, if there is an elegant way to perform this in one line without calling falseOrNumber() twice.

So I'm not looking for the obvious solution:

let i = falseOrNumber()
if (i) return i

This is nothing game-changing, but I've encountered similar situations several times in the past and I'd like to know if there is a cleaner way.

英文:

I have a function that returns either false or a number other than 0. Now I'm calling this function in another function to conditionally return the number.

function falseOrNumber() { ... }

function otherFunction() {
    // ...
    if (falseOrNumber()) return falseOrNumber()
    // ...
}

Now I was wondering, if there is an elegant way to perform this in one line without calling falseOrNumber() twice.

So I'm not looking for the obvious solution:

let i = falseOrNumber()
if (i) return i

This is nothing game changing, but I've encountered similar situations several times in the past and I'd like to know if there is a cleaner way.

答案1

得分: 3

If you assign the return value of the function to a variable inside the if statement, you can re-use it with the return statement:

function falseOrNumber() { ... }

function otherFunction() {
    // ...
    let result;
    if (result = falseOrNumber()) return result;
    // ...
}

If you want more elegance, there is probably a way to have one return statement for the entire function, instead of returning early. You can also use a comma expression to turn multiple expressions into a one-liner:

function otherFunction() {
    return falseOrNumber() || (other, code, here);
}

Update: your comment says that you have multiple functions like falseOrNumber. If so, you can do this:

function otherFunction() {
  return falseOrNumber() || somethingElse() || orSomethingElse();
}
英文:

If you assign the return value of the function to a variable inside the if statement, you can re-use it with the return statement:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function falseOrNumber() { ... }

function otherFunction() {
    // ...
    let result;
    if(result = falseOrNumber()) return result;
    // ...
}

<!-- end snippet -->

If you want more elegance, there is probably a way to have one return statement for the entire function, instead of returning early. You can also use a comma expression to turn multiple expressions into a one-liner.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function otherFunction() {
    return falseOrNumber() || (other, code, here);
}

<!-- end snippet -->

Update: your comment says that you have multiple functions like falseOrNumber. If so, you can do this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function otherFunction() {
  return falseOrNumber() || somethingElse() || orSomethingElse();
}

<!-- end snippet -->

答案2

得分: 2

你提到你的用例是在同一个otherFunction中多次调用这个函数。

如果你想要按顺序测试多个数字,可以这样做:

function otherFunction() {
    return falseOrNumber(1)
        || falseOrNumber(2)
        || falseOrNumber(3)
        || falseOrNumber(4)
        || falseOrNumber(5)
        || falseOrNumber(6)
        || falseOrNumber(7)
        || falseOrNumber(8)
        || falseOrNumber(9);
}

如果你需要在循环中执行这个操作,你可以共享一个变量:

function otherFunction() {
    let t = false;
    for (let i = 0; i < 100; i++)
        if (t = falseOrNumber(i))
            break;
    return t;
}
英文:

You mentioned that your use case is to call this many times over and over in the same otherFunction.

If you are trying to test several numbers in sequence, you can do it like so:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function otherFunction() {
    return falseOrNumber(1)
        || falseOrNumber(2)
        || falseOrNumber(3)
        || falseOrNumber(4)
        || falseOrNumber(5)
        || falseOrNumber(6)
        || falseOrNumber(7)
        || falseOrNumber(8)
        || falseOrNumber(9);
}

<!-- end snippet -->

If you need to do this in a loop, you can share one variable:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function otherFunction() {
    let t = false;
    for (let i = 0; i &lt; 100; i++)
        if (t = falseOrNumber(i))
            break;
    return t;
}

<!-- end snippet -->

答案3

得分: 1

如果您的用例如@maraaaaaaaa所说,如果这个提案被接受,将来您可能能够像这样做:

function otherFunction() {
  const testcases = [/* ... */]; // 一个非常昂贵的数组
  return testcases.values().map(falseOrNumber).find(Boolean);
}

testcases.values()返回一个迭代器,逐个遍历所有元素。.map()将它们与一个函数(在这种情况下是falseOrNumber)一起实时映射,但返回另一个迭代器,.find(Boolean)返回第一个映射的不为假的元素。

testcases.map()不同,testcases.values().map()是惰性的:它只在需要时进行评估。当涉及到Array#find()Iterator#find()时也是如此(目前还没有文档,只有这个)。

尝试它(这目前还不起作用):

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

console.config({ maximize: true });

const testcases = [1, 2, 3, 4];

console.log(
  testcases.values()
    .map(e =&gt; e ** 2)
    .find(e =&gt; e % 9 === 0)
);

<!-- language: lang-html -->

&lt;script src=&quot;https://gh-canon.github.io/stack-snippet-console/console.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

英文:

If your usecase is as what @maraaaaaaaa said, in the future you might be able to do something like this if this proposal gets accepted:

function otherFunction() {
  const testcases = [/* ... */]; // An extremely expensive array
  return testcases.values().map(falseOrNumber).find(Boolean);
}

testcases.values() returns an iterator which goes over all elements, one by one. .map() map those with a function (in this case, falseOrNumber) on the fly, yet returns another iterator and .find(Boolean) returns the first mapped element which is not falsy.

Unlike testcases.map(), testcases.values().map() is lazy: it only evaluate as needed. This is also the case when it comes to both Array#find() and Iterator#find() (there's no docs for this just yet, only this).

Try it (this doesn't work yet):

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

console.config({ maximize: true });

const testcases = [1, 2, 3, 4];

console.log(
  testcases.values()
    .map(e =&gt; e ** 2)
    .find(e =&gt; e % 9 === 0)
);

<!-- language: lang-html -->

&lt;script src=&quot;https://gh-canon.github.io/stack-snippet-console/console.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月6日 02:03:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76408933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定