質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • JavaScript

    15880questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

関数Aの実行結果がnullかundefinedの時のみに関数内に変数を新たに作らず、関数Bを実行させるには?

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 203

murabito

score 21

const hoge = (foo, bar) => (v) => foo(v) || bar(v);

foo(v)の結果がnullundefinedの時にbar(v)を実行させたいので、
foo(v) || bar(v)のようにしているのですが、これだと、foo(v)の結果がfalsyな値の場合、
bar(v)が実行されてしまいます。

const zero = (v) => 0 * v;
const double = (v) => 2 * v;

console.log(
    hoge(zero, double)(10)
)


この場合だと、0falsyなので、20が`返って来てしまいます。

const hoge = (foo, bar) => (v) => {
    const result = foo(v)
    return result != null ? result : bar(v);
}

一応、このようにfoo(v)の結果をローカル変数に入れてから、foo(v)の結果がnullまたはundefinedではないかをチェックすれば、 期待する動きにはなるのですが、このようにローカル変数を作らないと期待する結果は得られないでしょうか?

const hoge = (foo, bar) => (v) => {
    return foo(v) != null ? foo(v) : bar(v);
}

foo(v)をこのように2回呼ぶことも出来るでしょうが、これは非効率なので避けたいところです。

const hoge = (foo, bar) => (v) => foo(v) || bar(v);


このように全て、引数に渡ってくる値のみで完結させたいのですが、何か方法があれば教えて頂ければ幸いです。

※ 不可能な場合はそれが答えだと思います。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • _hiro

    2018/05/11 21:29 編集

    回答ではないですが、0!=nullはtrueです。 Number.isNaNか (result!==null && result!==undefine)な判定にする必要があります。

    キャンセル

  • murabito

    2018/05/11 21:42 編集

    「0!=nullはtrue」で問題ありません。今回はfoo(v)の結果がundefinedかnullの時のみbar(v)を実行したいので大丈夫です。

    キャンセル

  • _hiro

    2018/05/11 21:51

    すみません。勘違いしてました。

    キャンセル

回答 3

checkベストアンサー

+6

こういうことでしょうか。

const f = (foo, bar) => v => (x => x != null ? x : bar(v))(foo(v))

f((x => 0), (x => 2 * x))(10)
// 0
f((x => null), (x => 2 * x))(10)
// 20
f((x => undefined), (x => 2 * x))(10)
// 20

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/12 23:09

    ありがとうございます。即時実行関数使えば良かったのですね。

    キャンセル

  • 2018/05/13 10:07

    この回答は x != null を別の関数に追い出す処理をしていますが、質問文のコードと比べてどのようなメリットが考えられるでしょうか。
    個人的には、「関数コスト分、処理が増える」というデメリットが追加されているように読めてしまいます。

    キャンセル

  • 2018/05/13 10:17

    ローカル変数を使わず、foo を2回呼び出さずにやるにはどうするかという質問だったので、パズル的な問題だと思って回答しました。
    確かに実用的にはメリットが無いので自分なら普通にローカル変数を使って書くと思います。

    キャンセル

  • 2018/05/13 10:28

    なるほど、パズル的な問題としての回答でしたか。
    高評価が6つ付いていたので、私の想定できない部分でメリットがあるのかと思って焦りました。パズル的思考なら納得です。

    キャンセル

+3

ローカル変数が入るなぁ。

const hoge = ( foo, bar, i ) => v => (  ( i = foo( v ) ), ( i != null ? i : bar( v ) ) );

動くサンプル:https://jsfiddle.net/kuqtn37b/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

v == null;
v != null;

私はこの書き方が嫌いです。
変数には「入るべき型」を決めてから代入値を決めますが、nullが入りうるtruthyな型はObject型しかあり得ないからです。
つまり、truthy もしくは falsy で基本的に事足ります。

Re: murabito さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    node.jsのmodule.exportsで循環参照

    あるwebアプリを作っててそこではexpressとsocketioを使用しています。 expressのインスタンスの処理等とルーティングを分けようと思って app.js

  • 解決済

    apply()やcall()を使う機会を知りたい

    apply()、call()メソッドについて この2つのメソッドについては、使用している実際のコードを目にすることもあり、これまでにもネットで調べて自分でカスタマイズしつつ検証し

  • 解決済

    MapをJson文字列にする方法について

    前提・実現したいこと https://teratail.com/questions/65726 上記質問に回答しまして、「連想配列をループするにはfor...inか、あるいはM

  • 解決済

    jQuery Deferredを使用したアニメーション2

    お世話になっております。 jQueryのDeferredを使用して .box1,box2のアニメーション実行後 .box3のアニメーション実行 .box3アニメーション実行後.

  • 解決済

    nodeのutil.promisifyの実装について

    https://github.com/nodejs/node/blob/master/lib/internal/util.js#L256-308 nodeのpromisifyの

  • 解決済

    C++でメンバ関数をクラス外の関数から呼び出す方法 on Arduino

    ArduinoのattachInterruptにメンバー関数を割り当てる方法について質問です。 このページの回答を参考に test_class.ino #include "te

  • 解決済

    Javaの抽象クラスに抽象フィールドを持たせる方法

    私は数学関係のプログラムを作っていて、その中で体を表現するための抽象クラスを作ったのですが、0と1の存在をどのように表せばよいかわかりません。 具体的には、下のコードのzero()

  • 解決済

    jqueryでn文字目の正規表現

    みなさんすいません。 昨日お出しした問題に不備があり過ぎて申し訳ないです。 そして回答をたくさんくださりありがとうございます。 実装したい事としては、 カウントアップする数

同じタグがついた質問を見る

  • JavaScript

    15880questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。