6

私は2つのjavascriptオブジェクトを持っています:

var a = {
    x: 1, 
    y: {
        faz: 'hello', 
        baz: ''
    },
    z: [1, 2]
};


var defaults = {
    x: 2,
    y: {
        faz: '', 
        baz: ''
    },
    z: [1, 2]
};

デフォルトaとは異なるフィールドのみを保持したい:

a = remove_defaults(a, defaults); // <---- i need this fnc
{
    x: 1,
    y: {
        faz: 'hello'
    }
}

目標は、(URLを介して)状態として機能するオブジェクトからデフォルト値を削除することです。状態にはネストされたフィールドを含めることができるため、浅い比較では不十分です。リーフ値はすべてプリミティブ(数値、文字列、ブール)です。

(これはunderscore.js_.defaults()方法の反対に少し似ています)

これを達成するための最良の方法は何ですか?


underscore.jsそれが役立つ場合、ソリューションは使用できますが、使用できませんjquery

4

3 に答える 3

3

これを試して:

function removeDuplicates(a, defaults, result) {
  for (var i in a) {
    if (i in defaults) {
      if (typeof a[i] == "object" 
          && typeof defaults[i] == "object"
          && Object.prototype.toString.call(defaults[i]) !== '[object Array]') {
        result[i] = removeDuplicates(a[i], defaults[i], {});
      } else if (a[i] !== defaults[i]) {
        result[i] = a[i];  
      }
    } else {
      result[i] = a[i];
    }
  }

  return result;
}


var result = removeDuplicates(a, defaults, {});
于 2012-06-13T14:34:46.797 に答える
1
function remove_defaults(obj, defaults) {
  for (var i in obj) {
    if (typeof obj[i] == 'object') {
      obj[i] = remove_defaults(obj[i], defaults[i]);
      continue;
    }
    if (defaults[i] !== undefined && obj[i] == defaults[i]) {
      delete obj[i];
    }
  }
  return obj;
}

フィドル: http: //jsfiddle.net/ybVGq/

于 2012-06-13T14:40:19.680 に答える
0

私自身の見解:

function no_defaults(obj, defaults) {
    if ((obj instanceof Array) && (defaults instanceof Array)) {
        var result = _.difference(obj, defaults);
        return _.isEmpty(result) ? undefined : result;
    }
    if ((obj instanceof Array) || (defaults instanceof Array))
        return _.clone(obj);
    if (typeof obj == "object" && typeof defaults == "object") {
        var result = {};
        for (var prop in obj) {
            var res = prop in defaults ? no_defaults(obj[prop], defaults[prop]) : _.clone(obj[prop]);
            if (res !== undefined)
                result[prop] = res;
        }
        return _.isEmpty(result) ? undefined : result;
    }
    return _.isEqual(obj, defaults) ? undefined : _.clone(obj);
}

これはオブジェクトをディーププロセスしますが、配列は処理しないことに注意してください。配列は、直接要素の浅い違いに対してのみ処理されます。要素自体が必要な場合no_default、この関数は処理しません。しかし、これは私の意図したユースケースには問題ありません。

于 2012-06-13T19:30:38.903 に答える