从JSON数组中删除重复的对象

我有一个看起来像这样的数组:

var standardsList = [

{"Grade": "Math K", "Domain": "Counting & Cardinality"},

{"Grade": "Math K", "Domain": "Counting & Cardinality"},

{"Grade": "Math K", "Domain": "Counting & Cardinality"},

{"Grade": "Math K", "Domain": "Counting & Cardinality"},

{"Grade": "Math K", "Domain": "Geometry"},

{"Grade": "Math 1", "Domain": "Counting & Cardinality"},

{"Grade": "Math 1", "Domain": "Counting & Cardinality"},

{"Grade": "Math 1", "Domain": "Orders of Operation"},

{"Grade": "Math 2", "Domain": "Geometry"},

{"Grade": "Math 2", "Domain": "Geometry"}

];

而且我需要删除重复项,以便保留类似以下内容:

var standardsList = [

{"Grade": "Math K", "Domain": "Counting & Cardinality"},

{"Grade": "Math K", "Domain": "Geometry"},

{"Grade": "Math 1", "Domain": "Counting & Cardinality"},

{"Grade": "Math 1", "Domain": "Orders of Operation"},

{"Grade": "Math 2", "Domain": "Geometry"}

];

我尝试安装underscore.js并使用._uniq,但这似乎仅key:value在对象中出现一对时才起作用。我似乎无法使它跨多个键工作。

当我尝试类似的东西:

var uniqueStandards = _.uniq(standardsList, function(item, key, Domain){

return item.Domain;

});

我只得到前三个唯一值(每个年级一个)。但是我需要所有年级和领域的唯一值。是否有一种简单的方法将两个键都馈给_.uniq函数?

最终,我需要一个列表,其中每个唯一的等级作为标题,唯一的域作为列表项,以传递到HTML页面中。我可能会犯错,因此,如果有更简单的方法来实现最终目标,则可以公开征求意见。

提前致谢!

得到一些好的回应,并想澄清我的最终目标是什么。我正在尝试以HTML形式创建一系列列表:

<div>

<h3>Math K</h3>

<li>Counting & Cardinality</li>

<li>Geometry</li>

</div>

<div>

<h3>Math 1</h3>

<li>Counting & Cardinality</li>

<li>Orders of Operation</li>

</div>

<div>

<h3>Math 2</h3>

<li>Geometry</li>

</div>

我最初的想法是创建一个数组,然后将其推入<div>页面中的元素中。$("#divid").append(array)

回答:

最终,我需要一个列表,其中每个唯一的等级作为标题,唯一的域作为列表项,以传递到HTML页面中。我可能会犯错,因此,如果有更简单的方法来实现最终目标,则可以公开征求意见。

因此,您实际上并不需要您所要求的格式的输出数组。

在这种情况下,我将通过一个非常简单有效的解决方案直接进行追赶:

var grades = {};

standardsList.forEach( function( item ) {

var grade = grades[item.Grade] = grades[item.Grade] || {};

grade[item.Domain] = true;

});

console.log( JSON.stringify( grades, null, 4 ) );

结果grades对象是:

{

"Math K": {

"Counting & Cardinality": true,

"Geometry": true

},

"Math 1": {

"Counting & Cardinality": true,

"Orders of Operation": true

},

"Math 2": {

"Geometry": true

}

}

这种方法的有趣之处在于它非常快。请注意,它仅对输入数组进行一次遍历,这与其他需要多次遍历的解决方案不同(无论您是自己编写还是_.uniq()为您自己编写)。对于少量商品,这无关紧要,但是对于较大的商品,请记住这一点。

有了这个对象,您现在拥有了运行任何代码或生成所需任何其他格式所需的一切。例如,如果确实需要您提到的确切数组输出格式,则可以使用:

var outputList = [];

for( var grade in grades ) {

for( var domain in grades[grade] ) {

outputList.push({ Grade: grade, Domain: domain });

}

}

JSON.stringify( outputList, null, 4 );

这将记录:

[

{

"Grade": "Math K",

"Domain": "Counting & Cardinality"

},

{

"Grade": "Math K",

"Domain": "Geometry"

},

{

"Grade": "Math 1",

"Domain": "Counting & Cardinality"

},

{

"Grade": "Math 1",

"Domain": "Orders of Operation"

},

{

"Grade": "Math 2",

"Domain": "Geometry"

}

]

Rai在评论中询问此代码行的工作方式:

var grade = grades[item.Grade] = grades[item.Grade] || {};

这是获取对象属性或缺少属性时提供默认值的常见用法。请注意,=分配是按从右到左的顺序进行的。因此,我们可以按字面意义将其翻译为使用一条if语句和一个temp变量:

// Fetch grades[item.Grade] and save it in temp

var temp = grades[item.Grade];

if( ! temp ) {

// It was missing, so use an empty object as the default value

temp = {};

}

// Now save the result in grades[item.Grade] (in case it was missing)

// and in grade

grades[item.Grade] = temp;

var grade = temp;

您可能会注意到,在grades[item.Grade]已经存在的情况下,我们采用刚刚获取的值,并将其存储回相同的属性中。当然,这是不必要的,如果您像这样编写代码,则可能不会这样做。相反,您可以简化它:

var grade = grades[item.Grade];

if( ! grade ) {

grade = grades[item.Grade] = {};

}

那将是编写相同代码的完全合理的方法,并且效率也更高。与||成语所依赖的“真实性”相比,它还为您提供了一种更具体的测试方法。例如,if( ! grade

)您可能想使用而不是if( grade === undefined )

以上是 从JSON数组中删除重复的对象 的全部内容, 来源链接: utcz.com/qa/422754.html

回到顶部