从JSON阵列中删除重复的对象

时间:2014-05-07 02:47:12

标签: javascript jquery underscore.js

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

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)

17 个答案:

答案 0 :(得分:24)

function arrUnique(arr) {
    var cleaned = [];
    arr.forEach(function(itm) {
        var unique = true;
        cleaned.forEach(function(itm2) {
            if (_.isEqual(itm, itm2)) unique = false;
        });
        if (unique)  cleaned.push(itm);
    });
    return cleaned;
}

var standardsList = arrUnique(standardsList);

FIDDLE

这将返回

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

这正是你所要求的?

答案 1 :(得分:13)

  

最终,我需要一个列表,其中每个唯一等级作为标题,唯一域作为列表项传递到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语句和临时变量:

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

答案 2 :(得分:12)

我知道已经有很多答案,但对我来说最适合复杂json结构的答案是:

var arr = [{ "State": "RWCW", "desc": "WEST", "code": "RWCW", "level": 0, "save": "RWCW : WEST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RCSW", "desc": "SOUTHWEST", "code": "RCSW", "level": 0, "save": "RCSW : SOUTHWEST", "attribute1": "", "attribute2": "" }, { "State": "RECW", "desc": "NORTHEAST", "code": "RECW", "level": 0, "save": "RECW : NORTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RWCW", "desc": "WEST", "code": "RWCW", "level": 0, "save": "RWCW : WEST", "attribute1": "", "attribute2": "" }, { "State": "RWCW", "desc": "WEST", "code": "RWCW", "level": 0, "save": "RWCW : WEST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RCSW", "desc": "SOUTHWEST", "code": "RCSW", "level": 0, "save": "RCSW : SOUTHWEST", "attribute1": "", "attribute2": "" }, { "State": "RECW", "desc": "NORTHEAST", "code": "RECW", "level": 0, "save": "RECW : NORTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RWCW", "desc": "WEST", "code": "RWCW", "level": 0, "save": "RWCW : WEST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RECW", "desc": "NORTHEAST", "code": "RECW", "level": 0, "save": "RECW : NORTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RWCW", "desc": "WEST", "code": "RWCW", "level": 0, "save": "RWCW : WEST", "attribute1": "", "attribute2": "" }, { "State": "RCSW", "desc": "SOUTHWEST", "code": "RCSW", "level": 0, "save": "RCSW : SOUTHWEST", "attribute1": "", "attribute2": "" }, { "State": "RWCW", "desc": "WEST", "code": "RWCW", "level": 0, "save": "RWCW : WEST", "attribute1": "", "attribute2": "" }, { "State": "RCNW", "desc": "MIDWEST", "code": "RCNW", "level": 0, "save": "RCNW : MIDWEST", "attribute1": "", "attribute2": "" }, { "State": "RCSW", "desc": "SOUTHWEST", "code": "RCSW", "level": 0, "save": "RCSW : SOUTHWEST", "attribute1": "", "attribute2": "" }, { "State": "RECW", "desc": "NORTHEAST", "code": "RECW", "level": 0, "save": "RECW : NORTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RCNW", "desc": "MIDWEST", "code": "RCNW", "level": 0, "save": "RCNW : MIDWEST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RECW", "desc": "NORTHEAST", "code": "RECW", "level": 0, "save": "RECW : NORTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RCNW", "desc": "MIDWEST", "code": "RCNW", "level": 0, "save": "RCNW : MIDWEST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RCNW", "desc": "MIDWEST", "code": "RCNW", "level": 0, "save": "RCNW : MIDWEST", "attribute1": "", "attribute2": "" }, { "State": "RSCW", "desc": "SOUTHEAST", "code": "RSCW", "level": 0, "save": "RSCW : SOUTHEAST", "attribute1": "", "attribute2": "" }, { "State": "RECW", "desc": "NORTHEAST", "code": "RECW", "level": 0, "save": "RECW : NORTHEAST", "attribute1": "", "attribute2": "" }];

var clean = arr.filter((arr, index, self) =>
    index === self.findIndex((t) => (t.save === arr.save && t.State === arr.State)))

console.log(clean);

您可以直接尝试使用Chrome浏览器控制台并根据需要进行编辑。

我希望这有助于某人。

答案 3 :(得分:7)

复兴一个老问题,但我想在@ adeneo的答案上发布一个迭代。这个答案是完全一般的,但对于这个用例,它可能更有效(在我的机器上有几千个对象的数组很慢)。如果您知道需要比较的对象的特定属性,只需直接比较它们:

var sl = standardsList;
var out = [];

for (var i = 0, l = sl.length; i < l; i++) {
    var unique = true;
    for (var j = 0, k = out.length; j < k; j++) {
        if ((sl[i].Grade === out[j].Grade) && (sl[i].Domain === out[j].Domain)) {
            unique = false;
        }
    }
    if (unique) {
        out.push(sl[i]);
    }
}

console.log(sl.length); // 10
console.log(out.length); // 5

答案 4 :(得分:5)

针对您案例的Javascript解决方案:

console.log(unique(standardsList));

function unique(obj){
    var uniques=[];
    var stringify={};
    for(var i=0;i<obj.length;i++){
       var keys=Object.keys(obj[i]);
       keys.sort(function(a,b) {return a-b});
       var str='';
        for(var j=0;j<keys.length;j++){
           str+= JSON.stringify(keys[j]);
           str+= JSON.stringify(obj[i][keys[j]]);
        }
        if(!stringify.hasOwnProperty(str)){
            uniques.push(obj[i]);
            stringify[str]=true;
        }
    }
    return uniques;
}

答案 5 :(得分:3)

以下适用于我:

_.uniq(standardsList, JSON.stringify)

然而,对于很长的列表,这可能会很慢。

答案 6 :(得分:2)

我需要对JSON对象进行一些重复数据删除,所以我偶然发现了这个页面。但是,我使用了简短的ES6解决方案(不需要外部库),在Chrome Dev Tools Snippets中运行它:

const data = [ /* any list of objects */ ];
const set = new Set(data.map(item => JSON.stringify(item)));
const dedup = [...set].map(item => JSON.parse(item));
console.log(`Removed ${data.length - dedup.length} elements`);
console.log(dedup);

答案 7 :(得分:2)

**以下方法按您的方式进行。它根据所有属性值过滤数组。 **

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

const removeDupliactes = (values) => {
  let concatArray = values.map(eachValue => {
    return Object.values(eachValue).join('')
  })
  let filterValues = values.filter((value, index) => {
    return concatArray.indexOf(concatArray[index]) === index

  })
  return filterValues
}
removeDupliactes(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"}] 

答案 8 :(得分:1)

几个月前我在网上找到了一个解决方案,但不记得来源。感谢作者。解决方法如下。

// Example use case
const students = [
    {
        "m_name": "Jason",
        "m_id": "1",
        "age": 18,
        "subject": "Biology"
    },
    {
        "m_name": "Jason",
        "m_id": "1",
        "age": 18,
        "subject": "Chemistry"
    },
    {
        "m_name": "Sameer",
        "m_id": "2",
        "age": 18,
        "subject": "English"
    },
    {
        "m_name": "Sameer",
        "m_id": "2",
        "age": 18,
        "subject": "History"
    },
    {
        "m_name": "Philip",
        "m_id": "3",
        "age": 18,
        "subject": "Drama"
    }
]

// Function to merge by student name (or ID)
const groupBy = key => array =>
    array.reduce((objectByKeyValue, obj) => {
        const value = obj[key];
        objectByKeyValue[value] = (objectByKeyValue[value] || []).concat(obj);
        return objectByKeyValue;
    }, {});

// Replace with the key name
const groupBy_StudentName = groupBy('m_name') // or groupBy('m_id')

// Now pass your array name here
const grouped = groupBy_StudentName(students)

// Check your answer
console.log(grouped)

// Output

{
    "Jason": [
        {
            m_name: 'Jason',
            m_id: '1',
            age: 18,
            subject: 'Biology'
        },
        {
            m_name: 'Jason',
            m_id: '1',
            age: 18,
            subject: 'Chemistry'
        }
    ],
        "Sameer": [
            {
                m_name: 'Sameer',
                m_id: '2',
                age: 18,
                subject: 'English'
            },
            {
                m_name: 'Sameer',
                m_id: '2',
                age: 18,
                subject: 'History'
            }
        ],
            "Philip": [
                {
                    m_name: 'Philip',
                    m_id: '3',
                    age: 18,
                    subject: 'Drama'
                }
            ]
}

答案 9 :(得分:1)

我在这里发现每个答案的计算成本都很高,所以我们需要一个答案:

  • 高效
  • 短而优雅
  • 而且易于计算。

使用地图

let 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" }],
    map = {};

for (let list of standardsList) {
    map[Object.values(list).join('')] = list;
}
console.log('Using Map', Object.values(map));

使用集合

let 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" }],
    set = new Set, results = [];

for (let list of standardsList) {
    let id = Object.values(list).join('');
    if (!set.has(id)) {
        set.add(id);
        results.push(list);
    }
}
console.log('Using Set', results);

答案 10 :(得分:1)

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

standardsList = standardsList.filter((li, idx, self) => self.map(itm => itm.Grade+itm.Domain).indexOf(li.Grade+li.Domain) === idx)

document.write(JSON.stringify(standardsList))

这是一种更容易实现的功能性方法

standardsList = standardsList.filter((li, idx, self) => self.map(itm => iem.Grade+itm.domain).indexOf(li.Grade+li.domain) === idx)

答案 11 :(得分:1)

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

 function uniqurArray(array){
                         var a = array.concat();
                        for(var i=0; i<a.length; i++) {
                            for(var j=i+1; j<a.length; j++) {
                                if(a[i].Grade === a[j].Grade){
                                    a.splice(j--, 1);
                                }
                            }
                        }

                        return a;
                    }

    uniqurArray(standardsList) // put this js in console and you get uniq object in array

答案 12 :(得分:0)

这是es6的短篇小说!

const nums = [
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC9233F2015",
  "AC9233F2015",
  "AC9233F2015",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E2",
  "AC8818E2",
  "AC8818E2",
  "AC8818E2",
  "AC9233F2015",
  "AC9233F2015",
  "AC9233F2015",
  "AC9233F2015",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E2",
  "AC8818E2",
  "AC9233F2015",
  "AC9233F2015",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  "AC8818E2",
  "AC8818E2",
  "AC8818E2",
  "AC8818E2",
  "ACB098F25",
  "ACB098F25",
  "ACB098F25",
  "ACB098F25",
  "AC8818E2",
  "AC8818E2",
  "AC8818E1",
  "AC8818E1",
  "AC8818E1",
  ]

Set是ES6中引入的新数据对象。   因为Set仅允许您存储唯一值。传递数组时,它将删除所有重复的值。

export const $uniquenums = [...new Set(nums)].sort(); 

答案 13 :(得分:0)

使用Map删除重复项。 (对于新读者)

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 grades = new Map();
standardsList.forEach( function( item ) {
    grades.set(JSON.stringify(item), item);
});

console.log( [...grades.values()]);

/*
[
  { 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' }
]
*/

答案 14 :(得分:0)

您可以使用lodash,下载here(4.17.15)

示例代码:

dataId | projectId | keywords
-------|-----------|--------
1      |     1     | keyword 1, keyword 2, keyword 3, keyword 4, keyword 1
2      |     2     | keyword 5, keyword 6, keyword 7

答案 15 :(得分:0)

使用此伪代码

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 newArr =[]
for(var i in standardsList){
    newArr.push(JSON.stringify(standardsList[i]))
}
var obj = {};
newArr= newArr.filter((item)=>{
    return obj.hasOwnProperty(item) ? false : (obj[item] = true);
})
standardsList.length = 0
for(var i in newArr){
    standardsList.push(JSON.parse(newArr[i]))
}
console.log(standardsList)

我选择了一个类似于你的样本数组。一旦你对它们进行拼接,它就更容易比较。然后你只需比较字符串。

答案 16 :(得分:0)

使用 Underscore 开箱即用有两种主要方法可以非常简洁地做到这一点。 cookie 怪物已经在问题正下方的 comment 中提到了第一个:

_.uniq(standardsList, item => item.Grade + item.Domain)

使用如上所示的直接字符串连接,在以下情况下可能会出现有问题的边缘情况:

var standardsList = [
    {Grade: 'abcdef', Domain: 'ghi'},
    {Grade: 'abc', Domain: 'defghi'}
];

因为两者都产生组合字符串 'abcdefghi' 尽管它们不等价。对此最简单的解决方案是插入一个您知道永远不会出现的子字符串作为 Grade 的后缀(或作为域的前缀),例如假设 ': ' 是这样一个子字符串:

_.uniq(standardsList, item => item.Grade + ': ' + item.Domain)

dpmemcry 在 answer 中已经提到了第二个。这是与 Underscore 兼容的版本:

_.uniq(standardsList, _.isEqual);

区别在于第一个解决方案只考虑您专门选择的字段,而第二个解决方案考虑所有字段,甚至执行递归比较。在某些情况下,这可能正是您想要的,而在其他情况下,它可能太贵了。

多一点努力,即通过编写自定义帮助程序函数,您可以在这些解决方案之间实现折衷,您可以选择要考虑的字段,而不必每次都写出串联表达式。这是编写该辅助函数的一种可能方法:

function byFields(fields, separator) {
    return function(item) {
        return _.map(fields, _.propertyOf(item)).join(separator);
    };
}

这是你如何使用它:

_.uniq(standardsList, byFields(['Grade', 'Domain'], ': '));

使用后一种方法,您还可以选择通过传递数组路径而不是字段列表中的字符串来执行选择性深度比较。这使您可以进行深入的属性查找,而不必强迫您在每个对象中一直递归。例如,假设每个项目的 Domain 属性是一个嵌套对象,如下所示:

var standardsList = [
    {Grade: "Math K", Domain: {id: 1, name: "Counting & Cardinality"}},
    // ...
];

那么你可以像这样使用上面的辅助函数,无需修改:

_.uniq(standardsList, byFields['Grade', ['Domain', 'id']], ': '));