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

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

ただいまの
回答率

90.02%

2つのJSONファイルをAJAXで読み込んで、一つにobjectにマージする方法を教えてください

解決済

回答 1

投稿

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

qwe001

score 83

jQuery(ver3系)を用いて、外部ファイルを読み込むコードを次のように書きました。

(function($){
    'use strict';

    const LIST_PATH_NEW = "./data/list.json";
    const LIST_PATH_OLD = "./list.json";

    function loadJson(jsonPath)
    {
        var defer = $.Deferred();

        $.ajax({
            type : "GET",
            url : jsonPath,
            dataType: "json",
            success: defer.resolve,
            error: defer.reject
        });

        return defer.promise();
    }

    function getList(listPath)
    {
        return loadJson(listPath);
    }

    function getNewList()
    {
        return getList(LIST_PATH_NEW);
    }

    function getOldList()
    {
        return getList(LIST_PATH_OLD);
    }

    $(function(){
        var newList = getNewList();
        var oldList = getOldList();

        newList.done(function(data){
            var myList = data.list;
            console.log(myList);
        });

        oldList.done(function(data){
            var myList = data.list;
            console.log(myList);
        });

        // ★ ここらへんで array_merge みたいなことがしたいです ★

    });

})(jQuery);

それぞれのAJAXから返ってくるデータは次のような形です。(簡略化しています)

{
  "list": [
    {
      "image": "aaa.jpeg",
      "title": "新しいやつ",
      "date": "2019-03-17",
    },
  ]
}

各オブジェクトのプロパティ名は両方とも同じです。
データの総数は古いほうが500件あまりで固定、新しいほうは5件あまりで今後増大していきます。

過去のデータと、新しいデータを一つのオブジェクトデータにマージし、
それをもとにフロントで色々する、といった感じです。

これら2つのデータは別々の管理システムから出力されており、
データのインポート/エクスポートの仕組みもないため、元ファイル自体をマージするということはできません。
(直接編集したところで次にシステムから出力された時に編集内容が上書きされる)

PHPで言うところの array_merge みたいなことをして、一つのオブジェクトデータにしたいのですが、
どのようにすれば実現できますでしょうか。

皆様お知恵を貸してください。よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2019/03/18 13:34

    追加した結果、どのような内容になるのか、inputとoutputのデータをなるべく具体的に例示してください。
    結局はオブジェクトのマージなのでその角度から調べればある程度参考になりそうな情報は出てきそうですが、そのあたりは何か調べてみましたか?

    キャンセル

回答 1

checkベストアンサー

+3

それぞれのAJAXから返ってくるデータは次のような形です。(簡略化しています)
各オブジェクトのプロパティ名は両方とも同じです。

簡略化しすぎです。
何を簡略化したのですか?
そして、マージしたい2つのJSONデータはどこに差異があるんですか?

オブジェクトに単体でlistというプロパティがあるのって中々の変態ですね。
普通配列じゃないですか?
つまり、他にもエラー理由やお知らせデータなんかも入ってくるんですか?
これらもマージしなさいみたいな話になってくると、読み取りようがないので勘弁してください。

この辺の理由から回答者は色々想像を働かせて、当てずっぽうな回答をせざるを得ません。
良い質問ってのはどうしても技量が求められますので、駄目だったら色々追記してみてください。


どちらも下記のデータである事と想定します。

  • オブジェクトのJSONであること
  • listプロパティ(中身は必ず配列)を所持している
  • list配列はオブジェクトの配列である
  • list配列内の各オブジェクトはプロパティ名等は統一されている

// ★ ここらへんで array_merge みたいなことがしたいです ★

無理、Ajaxは非同期です。
だからわざわざnewList.doneとかやってるんです。

取っ掛かりは下記を勉強しましょう。
jQuery.when() で、複数の非同期処理を扱う

jQuery.whenを使って両方のAjax通信が終わったタイミングで動かすにはこんな感じになるでしょう。

$(function(){
  var newList = getNewList();
  var oldList = getOldList();

  $.when(newList, oldList)
    .done(function(dataNew, dataOld){
      var myListNew = dataNew.list;
      var myListOld = dataOld.list;

      // ここらへんでarray_mergeみたいなことがしたい
    });

マージのやり方

JavaScriptはPHPより進んだオブジェクト指向言語ですので、
連想配列的な存在であるオブジェクト、配列、関数、文字列、数値、論理値は
全てプロパティやメソッドを所持しています。

余談ですが、
JavaScriptは文字列・数値・論理値はプリミティブ値としても振る舞うので、
プロパティを参照した時だけ一時的にオブジェクトに変身し、
行の最後でプリミティブ値に戻るというヘンテコな動きをします。

// PHPではインスタンス以外はプロパティやメソッドを所持していないのでエラーになる
('hoge,piko')->split(',');

// なのでPHPではこうする
explode(',', 'hoge,piko');

// JavaScriptではString型がメソッドを所持しているのでアクセスしても許される
"hoge,piko".split(',');

JavaScriptの配列(Array型のインスタンス)は配列自身が色々とメソッドを所持しています。
例えば、配列AとBをマージするArray.prototype.concatというメソッドが最初から用意されているので、
配列のマージ結果が欲しいという場合はそれを実行するだけでおしまいです。

var arr1 = [1, 2];
var arr2 = [3, 4];

console.log(arr1.concat(arr2));
// [1, 2, 3, 4]

console.log(arr1);
// [1, 2] <- arr1が破壊されないので安心して使えるね

console.log(arr2);
// [3, 4] <- こちらも無事

PHPが配列操作の関数を沢山覚える事が力になるのと同様に、
JavaScriptは型が所持しているメソッドを沢山覚えるのが力になる言語です。
JavaScriptを本気でやるならメソッドに焦点を当てて学習してみてください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/03/18 15:01

    大変丁寧なご回答、ありがとうございます。whenメソッドとconcatメソッドを使うことで考えた通りのことが実行できました。こちらBAとさせて頂きます。

    キャンセル

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

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