2013-04-23 31 views
1

我正在大型数据集上运行脚本以扩展现有信息。 e.g:从单个赋值操作避免重复的JS对象属性?

... 
{ 
    id : 1234567890 
}, 
{ 
    id : 1234567891 
}, 
... 

成为

... 
{ 
    id : 1234567890, 
    Name : "Joe" 
}, 
{ 
    id : 1234567891, 
    Name : "Bob" 
}, 
... 

我通过下面的代码实现这一点:

for(var cur in members) 
{ 
    curMember = members[cur]; 
    // fetch account based on curMember.id to 'curAccount' 

    if(curAccount != null) 
    { 
     curMember.DisplayName = curAccount.DisplayName; 
    } 
} 

在大多数情况下,这种按预期工作。然而,在一段时间后(在数万项的顺序),结果是这样的:

... 
{ 
    id : 1234567891, 
    Name : "Bob", 
    Name : "Bob" 
}, 
... 

我现在已经是一个无效的格式,无法通过数据库来读取数据,因为重复的属性名称没有意义。脚本重新运行时发生随机输入,而不是每次都是相同的。我需要一种方法来防止这种情况发生,或者检测到它发生了,所以我可以简单地重新处理条目。任何人都知道这里发生了什么?

编辑:进一步调查后,只有当被修改的对象来自MongoDB查询时,才会出现问题。看起来,如果代码显式地将一个值设置为相同的元素名称多次,该字段将被复制。所有相同名称的元素似乎都设置为最近指定的值。如果仅在我的原始问题中分配一次,则只会极少重复。我正在使用MongoDB 2.4.1。

+0

a)不要在数组中使用for-in-loop b)在js对象上不可能有重复的属性。你的JS引擎错误(你使用哪一个)?你究竟如何得到这个输出? – Bergi 2013-04-23 14:47:04

+0

@Bergi - 我相信JS引擎不是越野车。主要是因为没有JS引擎会包含这样一个愚蠢的错误。其次,因为JS对象通常以红黑树或散列表的形式实现,从而防止两个字段具有相同的名称。 – 2013-04-23 15:00:08

+1

a)感谢您的提示,将改变它 b)我意识到这应该是完全不可能的,没有意义!我在使用ES5的MongoDB 2.4.1上运行它。详情:http://docs.mongodb.org/manual/release-notes/2.4-javascript/。循环结束后但在提交回数据库之前,我通过printjson(成员)获得输出。 – Kevin 2013-04-23 15:02:00

回答

1

我真的不知道你的问题。如果将相同的属性名称应用于ECMAscript中的对象,则该属性将被覆盖。你的代码片段中的结构永远不会以活动对象(不包括JSON字符串)的形式存在。

如果你只是想检测尝试创建一个属性,它已经在那儿了,你要么需要有一个对象引用预先缓存(这样你就可以循环它的键) - 或 - 您需要申请ES5严​​格模式

"use strict"; 

位于文件或函数的顶部。这将确保您的解释器将尝试创建两个相同的属性键时抛出异常。 您当然可以使用 try - catch语句来拦截那个失败。

好像你不能拦截因为违反严格模式违规而抛出的错误