从JSON阵列中删除重复的对象 [英] Remove Duplicate objects from JSON Array

查看:99
本文介绍了从JSON阵列中删除重复的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的数组:

I have an array that looks like this:

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"}
];

我需要删除重复项,以便保留这样的内容:

And I need to remove the duplicates so that something like this remains:

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 pair出现在对象中。我似乎无法让它跨多个键工作。

I've tried installing underscore.js and using ._uniq but that only seems to work when a single key:value pair appears in the object. I can't seem to get it to work across multiple keys.

当我尝试这样的事情时:

When I try something like:

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

我只获得前三个唯一值(每个等级一个)。但我需要所有等级和领域的所有独特价值。是否有一种简单的方法可以将两个键都输入_.uniq函数?

I only get the first three unique values (one per grade). But I need all the unique values across both grade and domain. Is there a simple way to feed both keys to the _.uniq function?

最后,我需要一个列表,其中每个唯一等级作为标题,唯一的域名为要传递到HTML页面的列表项。我可能会犯这个错误,所以如果有一个更简单的方法来实现这个目标,我愿意接受这个想法。

Ultimately, I need a list with the each unique grade as the header and the unique domains as the list items to pass into an HTML page. I may be going about this wrong, so if there is an easier way to accomplish that end goal, I am open to ideas.

提前致谢!

编辑:获得一些好的回复并想要澄清我的最终目标是什么。我正在尝试使用以下格式的HTML创建一系列列表:

Getting some good responses and wanted to clarify what my end goal was. I'm trying to create a series of lists in HTML of the form:

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

My original though was to create an array and push that into the <div> element on the page with $("#divid").append(array)

推荐答案


最终,我需要一个列表,其中每个唯一等级作为标题,唯一域作为列表项传递到HTML页面。我可能会想到这个错误,所以如果有更简单的方法来实现最终目标,我愿意接受这些想法。

Ultimately, I need a list with the each unique grade as the header and the unique domains as the list items to pass into an HTML page. I may be going about this wrong, so if there is an easier way to accomplish that end goal, I am open to ideas.

所以你实际上并不需要你所询问的格式的输出数组。

So you don't actually need that output array in the format you asked about.

在这种情况下,我会直接切入追逐,非常简单有效解决方案:

That being the case, I would cut directly to the chase with a very simple and efficient solution:

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

结果成绩对象是:

{
    "Math K": {
        "Counting & Cardinality": true,
        "Geometry": true
    },
    "Math 1": {
        "Counting & Cardinality": true,
        "Orders of Operation": true
    },
    "Math 2": {
        "Geometry": true
    }
}

这种方法的一个有趣之处在于它非常快。请注意,它只通过输入数组一次,不像其他需要多次传递的解决方案(无论你是自己编写还是 _。uniq()为你完成)。对于少数项目而言这无关紧要,但最好记住更大的列表。

One interesting thing about this approach is that it is very fast. Note that it makes only a single pass through the input array, unlike other solutions that require multiple passes (whether you write them yourself or whether _.uniq() does it for you). For a small number of items this won't matter, but it's good to keep in mind for larger lists.

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

And with this object you now have everything you need to run any code or generate any other format you want. For example, if you do need the exact array output format you mentioned, you can use:

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 问在评论中这行代码是如何工作的:

Rai asks in a comment how this line of code works:

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

这是获取对象属性或在缺少属性时提供默认值的常用习惯用法。请注意, = 分配是按从右到左的顺序完成的。因此,我们可以将其翻译为使用 if 语句和临时变量:

This is a common idiom for fetching an object property or providing a default value if the property is missing. Note that the = assignments are done in right-to-left order. So we could translate it literally to use an if statement and a temp variable:

// 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;

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

You may notice that in the case where grades[item.Grade] already exists, we take the value we just fetched and store it back into the same property. This is unnecessary, of course, and you probably wouldn't do it if you were writing the code out like this. Instead, you would simplify it:

var grade = grades[item.Grade];
if( ! grade ) {
    grade = grades[item.Grade] = {};
}

这是编写相同代码的完美合理方式,而且更多效率也很高。它还为您提供了一种方法来进行更具体的测试,而不是 || idiom所依赖的真实性。例如,如果($ grade)而不是,您可能想要使用 if(grade === undefined)

That would be a perfectly reasonable way to write the same code, and it's more efficient too. It also gives you a way to do a more specific test than the "truthiness" that the || idiom relies on. For example instead of if( ! grade ) you might want to use if( grade === undefined ).

这篇关于从JSON阵列中删除重复的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆