7

これはよくある問題だと思いますが、解決策が見つからないようです。JSON構成ファイルを使用して、オブジェクトと配列を含むjQueryオブジェクトを拡張します。

オブジェクトと単純なプロパティについては、上書きしたいと思います(extendうまくいきます)。

配列の場合、既存のアイテムがある場合とない場合があります。

現在、配列は最初の要素を上書きするだけです

var sourceObj = {propterty:"change Me",anArray:[{name:"first"},{name:"second"}]},
    configJSON = '{"propterty":"New Val","anArray":[{"name":"third"}]}',
    configObj = JSON.parse(configJSON);

$.extend(true,sourceObj,configObj);

http://jsfiddle.net/PmuwV/

これは次を返します:

{propterty:"New Val" , anArray:[{name:"third"},{name:"second"}}

代わりに入手できますか:

{propterty:"New Val",anArray:[{name:"first"},{name:"second"},{name:"third"}]}

また、「最初の」オブジェクトと「2番目の」オブジェクトの更新も可能ですか?

"anArray":[{"name":"second","newProp":"add newProp to second"}]

extend配列アイテムを比較し、ルールに基づいて拡張または追加したり、「名前」などのプロパティ値を設定したりするように変更できますか?

アドバイスやアドバイスをありがとう。

4

4 に答える 4

2

このソリューションを使用しましたhttp://jsfiddle.net/PmuwV/2/ から変更2つのJavaScriptオブジェクトのプロパティを動的にマージするにはどうすればよいですか?jQueryのextendメソッドに相当するJavaScriptからも

isDOMNode()が必要です。マージ後に重複をクリーンアップする必要がある配列に、jqueryマージで追加しました(はい、私も汚れています)。extendのJqueryソースは非常によく似ていますが、これがより読みやすいことがわかりました。

function mergeRecursive() {
  // _mergeRecursive does the actual job with two arguments.
  var _mergeRecursive = function (dst, src) {
    if ( isDOMNode(src) || typeof src!=='object' || src===null) {
      return dst; 
    }

    for ( var p in src ) {

//my added bit here - [SB]
      if ($.isArray(src[p])){
          $.merge(dst[p],src[p]);
          var dupes = {},
               singles = [];
          $.each(  dst[p], function(i, el) {
             if ((dupes[el.name] > -1) &&  (el.name)) {
                 $.extend(singles[dupes[el.name]],el);
             }else{
                  if (el.name ){
                     dupes[el.name] = i;
                  }
                 singles.push(el);
             }
         });
         dst[p] = singles;
         }
         continue;        
      }
//the rest is original - [SB]

      if( !src.hasOwnProperty(p) ) continue;
      if ( src[p]===undefined ) continue;
      if ( typeof src[p]!=='object' || src[p]===null) {
        dst[p] = src[p];
      } else if ( typeof dst[p]!=='object' || dst[p]===null ) {
        dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]); 
      } else {              
        _mergeRecursive(dst[p], src[p]);
      }
    }
    return dst;
  }

  // Loop through arguments and merge them into the first argument. 
  var out = arguments[0];
  if ( typeof out!=='object' || out===null) return out;
  for ( var i=1, il=arguments.length; i<il; i++ ) {
    _mergeRecursive(out, arguments[i]);
  }
  return out;
}
于 2012-11-08T04:02:12.027 に答える
2

lodashライブラリを使用すると非常に簡単です

var targetObj = {
    customerId: "123", 
    orders: [
        "item1", "item2"
    ]
};

var otherObj = {
    customerName: "John", 
    orders: [
        "item3", "item4"
    ]
};

_.merge(targetObj, otherObj, function (a, b) {
  if (_.isArray(a)) {
    return a.concat(b);
  }
});

結果は次のとおりです。

targetObj = {
    customerId: "123",
    customerName: "John",
    orders: [
        "item1", "item2", "item3", "item4"
    ]       
}
于 2015-08-21T13:06:51.723 に答える
0

私はこれが古いことを知っていますが、私はこの投稿を見つけ、上記のSteve Blacksコードを使用しましたが、いくつかのバグを見つけました:

  1. isArrayセクションの「continue」の前に余分な「}」があります。
  2. ソースに配列がまったくない場合はエラーがスローされるため、これをisArrayセクションに追加しました

    if ( !dst[p] ) {
        dst[p] = src[p];
        continue;
    }
    

したがって、完成したコードは次のようになります。

function isDOMNode(v) {
    if ( v===null ) return false;
    if ( typeof v!=='object' ) return false;
    if ( !('nodeName' in v) ) return false; 
    var nn = v.nodeName;
    try {
      v.nodeName = 'is readonly?';
    } catch (e) {
      return true;
    }
    if ( v.nodeName===nn ) return true;
    v.nodeName = nn;
    return false;
}

function mergeRecursive() {
    // _mergeRecursive does the actual job with two arguments.
    var _mergeRecursive = function (dst, src) {
        if ( isDOMNode(src) || typeof src!=='object' || src===null) {
            return dst; 
        }

        for ( var p in src ) {
            if ($.isArray(src[p])) {
                if ( !dst[p] ) {
                    dst[p] = src[p];
                    continue;
                }
                $.merge(dst[p],src[p]);
                var dupes = {}, singles = [];
                $.each( dst[p], function(i, el) {
                    if ((dupes[el.name] > -1) &&  (el.name)) {
                        $.extend(singles[dupes[el.name]],el);
                    } else {
                        if (el.name) {
                            dupes[el.name] = i;
                        }
                     singles.push(el);
                   }
                });
                dst[p] = singles;
                continue;        
            }

            if ( !src.hasOwnProperty(p) ) continue;
            if ( src[p]===undefined )     continue;
            if ( typeof src[p]!=='object' || src[p]===null) {
                dst[p] = src[p];
            } else if ( typeof dst[p]!=='object' || dst[p]===null ) {
                dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]); 
            } else {              
                _mergeRecursive(dst[p], src[p]);
            }
        }
        return dst;
    }

    // Loop through arguments and merge them into the first argument. 
    var out = arguments[0];
    if ( typeof out!=='object' || out===null) return out;
    for ( var i=1, il=arguments.length; i<il; i++ ) {
      _mergeRecursive(out, arguments[i]);
    }
    return out;
}
于 2015-10-07T18:20:08.607 に答える
0
<html>
<head>
<script type="text/javascript" src="./jquery-2.1.3.js"></script> <!-- for json extend / merge -->
<script type="text/javascript" src="./jQuery.extendext.min.js"></script> <!-- for json extend / merge - with array extend (instead of array overwrite) - https://github.com/mistic100/jQuery.extendext -->

<script>
var jsonResult = {};
var json1 =
{
    "properties":
    {
        "street_address": { "type": "string" },
        "city": { "type": "string" },
        "state": { "type": "string" }
    },
    "required": ["street_address", "city", "state"]
};
var json2 =
{
    "properties":
    {
        "country": { "type": "string" },
        "country-dial-code": { "type": "integer" },
        "country-short": { "type": "string" }
    },
    "required": ["country", "country-dial-code", "country-short"]
};
$.extendext(true, 'extend', jsonResult, json1, json2);
console.log(JSON.stringify(jsonResult));
/* output ->
{   "properties":
    {   "street_address":{"type":"string"},
        "city":{"type":"string"},
        "state":{"type":"string"},
        "country":{"type":"string"},
        "country-dial-code":{"type":"integer"},
        "country-short":{"type":"string"}
    },
    "required":["street_address","city","state","country","country-dial-code","country-short"]
}
*/
</script>
</head>
<body>
</body>
</html>
于 2016-01-29T07:56:52.373 に答える