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

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

ただいまの
回答率

88.64%

メソッドチェーンのような記述で配列をフィルタリングしたいが、そもそもメソッドチェーンの作り方が分からない。試しに作っても配列が返ってこない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,062

asagao

score 14

前提・実現したいこと

  • まず興味をもって開いていただきましてありがとう
  • 自分はプログラム初心者というより素人です
  • JavaScriptというより簡単な記述でDOM操作ができたJQueryのおかげでこの分野に興味をもった人間です。今まではWebの読み手側でした
  • 変数sampledataにオブジェクトが連続で規則正しく入った配列があります(最下部参照)。
    例えば「 日本人 且つ 女性 且つ 二十歳未満」にすべて合致するオブジェクトを抽出・フィルタリングしたいのですが、
    これをどうにかこうにかして以下のようなメソッドチェーンライクな記述法で、オリジナルの配列から条件フィルタリングして新たな配列を作成し返り値にしたいのです。
var sampledata = [{略},{略},{略},,,];
var newarray = sampledata.kokusekiis("Japanese").seibetsuis("female").nenreiislower(20);
var sampledata = [{略},{略},{略},,,];
var newarray = sampledata.itchi("nationality","Japanese").itchi("sex","female").miman("age",20);
  • どうしてこうしたいかというと自分が何度も絞り込みをやるからと、
    自分以外の人のページ視聴者にもF12から簡単に絞り込み作業をコマンド風にやってみてほしいからです
  • JQueryも好きなのでJQueryを使ったものと、依存しないネイティブなものの2パターン実現可能なのでしょうか? 
    できれば勉強のために2パターンあれば教えてもらえると助かります。
  • もうすでにこの世にこれを実現できるプラグインが存在してるよって場合は教えていただけるとすごく助かります。
  • もし土俵にもたってないちんぷんかんぷんな質問になってましたら、正直に叱ってもらって構いません。

自力で試したこと

まだつまみ食いレベルの自分で思いついたのは以下の2つの方法なんですが、 再利用しにくかったり、
関数の引数にその前の関数での戻り値を入れたり、 読みにくいです

 その1) 単発ならこれでいいのだけど・・・使い回しが効かない上に、視聴者はこんなの書けない
var japanesefemale1 = sampledata.filter(function(input) {
  if (input["nationality"] === "Japanese" && input["sex"] === "female" && input["age"] < 20) {
    return true
  }
});
console.log(japanesefemale1); //ちゃんと思い通りにフィルタリングした新たな配列が入っている
 その2) 予め関数作成し、繰り返して絞り込む
function itchi(input, key, value) {
  return input.filter(function(input) {
    if (input[key] === value) {
      return true
    }
  });
}
function miman(input, key, value) {
  return input.filter(function(input) {
    if (input[key] < value) {
      return true
    }
  });
}
var japanesefemale2 = miman(itchi(itchi(sampledata, "nationality", "Japanese"), "sex", "female"),"age", 20);//
console.log(japanesefemale2); //ちゃんと思い通りにフィルタリングした新たな配列が入っている
 その3)JQuery 拡張メソッドをネット上の資料をもとに見よう見まねで作ってみた

なお、鎖のようにメソッドチェーンさせるにはJQueryオブジェクトの状態で都度返さないとチェーンが途切れることはネット上の資料を読んで学びました。

(function($) {
  $.fn.extend({
    hitoshii: function(key, value) { //失敗。これを使っても空っぽの配列しか返ってこない
      return (this.filter(function(item, index, input) {
        if (item[key] === value) return true
      }));
    },
    getfirst: function() { //成功。思い通りの結果が返ってきた
      return this[0];
    },
    getlast: function() { //成功。思い通りの結果が返ってきた
      return this[this.length - 1];
    },
    getvar: function(num) { //成功。思い通りの結果が返ってきた
      if (0 <= num && num < this.length) return this[num];
    }
  });
})(jQuery);
$(sampledata).hitoshii("nationality", "Japanese"); //失敗。空っぽの配列[]が返ってきた
$(sampledata).getfirst(); //成功。
$(sampledata).getlast(); //成功。
$(sampledata).getvar(3); //成功。

最後に

  • Webkit系ブラウザのデベロッパーツールのコンソールで操作
  • JQueryのバージョンは3.1.1を使用

最後までお読み頂きありがとうございました

var sampledata = [{
  "age": 21,
  "sex": "male",
  "id": 1001,
  "single": true,
  "nationality": "Japanese"
}, {
  "age": 10,
  "sex": "female",
  "id": 1002,
  "single": true,
  "nationality": "Japanese"
}, {
  "age": 18,
  "sex": "male",
  "id": 1003,
  "single": true,
  "nationality": "Chinese"
}, {
  "age": 23,
  "sex": "female",
  "id": 1004,
  "single": true,
  "nationality": "Japanese"
}, {
  "age": 15,
  "sex": "male",
  "id": 1005,
  "single": true,
  "nationality": "Japanese"
}, {
  "age": 29,
  "sex": "female",
  "id": 1006,
  "single": false,
  "nationality": "Chinese"
}, {
  "age": 36,
  "sex": "female",
  "id": 1007,
  "single": false,
  "nationality": "Korean"
}];
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

「メソッドチェーンの作り方」を探して試してみてはいかがでしょうか。

【メソッドチェーンの作り方 - あと味】
http://taiju.hatenablog.com/entry/20100307/1267962826

【JavaScriptでメソッドチェーンを作る - Qiita】
http://qiita.com/sawapi/items/279531c88709700d0ff1

【jQueryのメソッドチェーンのつなぎ方(2) [Javascript] All About】
https://allabout.co.jp/gm/gc/24166/

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/29 02:28

    回答ありがとうございます!
    結論を先に申し上げますと、やりたかったことがズバリできました!感謝感激です!

    1番上の「あと味」さんのページが非常にわかりやすかったうえに私にピンポイントな内容でした。
    さっそく見よう見まねで自分の書いた関数の中身(上述)をコピペして

    ```JavaScript
    Array.prototype.itchi = function(key, value) {
    return (this.filter(function(item, index, input) {
    if (item[key] === value) return true
    }));
    };
    Array.prototype.miman = function(key, value) {
    return (this.filter(function(item, index, input) {
    if (item[key] < value) return true
    }));
    };
    var sampledata = [{略},{略},{略},,,];
    sampledata.miman("age",20).itchi("nationality","Japanese");//成功!
    ```
    としたところ、うまくチェーンして絞り込んだ配列が返ってきました!
    うまくいきましたので、もう少し関数名を洒落たものにしますね。
    この度は短時間で解決に至るズバリの回答ありがとうございました!



    キャンセル

  • 2017/07/29 02:33

    Arrayのように元々有るオブジェクトを拡張するのは避けたほうが良いです。そのページ内で「ちょっとお行儀が悪いですが」と書かれているのはそういうことです。

    キャンセル

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

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

関連した質問

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

  • トップ
  • JavaScriptに関する質問
  • メソッドチェーンのような記述で配列をフィルタリングしたいが、そもそもメソッドチェーンの作り方が分からない。試しに作っても配列が返ってこない