2012-06-13 154 views
6

我有两个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

+1

递归迭代属性并比较它们的值。没有内置的方法。 –

回答

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, {}); 
+1

干杯!但是,“a&i”是什么?那会忽略所有的错误,像'false','0','''','undefined',这看起来像一个错误? – user124114

+1

你是正确的,我修复了代码。 – ioseb

+0

哦,我刚刚意识到那里有一个巨大的错误 - 所有复制的字段都转到了'result'的全局范围,而不是它们各自的子字段! – user124114

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/

+0

这会在结果中留下'z'数组。我认为@ ioseb的解决方案更好,因为一旦它们完全为空(=所有内部值都等于默认值),它也会删除嵌套对象。 – user124114

+0

是的,我注意到了。那是因为我使用'delete'而不是创建一个全新的数组。 – jeremyharris

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); 
} 

注意此深进程中的对象,而不是阵列。数组只处理其直接元素的浅差异 - 如果元素本身需要,则此函数不会执行此操作。但是这对我的预期用例很好。