dch*_*ess 33 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"}
];
Run Code Online (Sandbox Code Playgroud)
我需要删除重复项,以便这样的东西仍然存在:
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"}
];
Run Code Online (Sandbox Code Playgroud)
我已经尝试安装underscore.js并使用._uniq,但只有key:value在对象中出现一对时才会起作用.我似乎无法让它跨多个键工作.
当我尝试这样的事情:
var uniqueStandards = _.uniq(standardsList, function(item, key, Domain){
return item.Domain;
});
Run Code Online (Sandbox Code Playgroud)
我只得到前三个唯一值(每个等级一个).但我需要所有等级和领域的所有独特价值.是否有一种简单的方法可以将两个键都输入_.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>
Run Code Online (Sandbox Code Playgroud)
我原来的是创建一个数组并将其推送到<div>页面上的元素中$("#divid").append(array)
ade*_*neo 25
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);
Run Code Online (Sandbox Code Playgroud)
这将返回
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"}
];
Run Code Online (Sandbox Code Playgroud)
这正是你要求的?
Mic*_*ary 16
最终,我需要一个列表,其中每个唯一等级作为标题,唯一域作为列表项传递到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 ) );
Run Code Online (Sandbox Code Playgroud)
生成的grades对象是:
{
"Math K": {
"Counting & Cardinality": true,
"Geometry": true
},
"Math 1": {
"Counting & Cardinality": true,
"Orders of Operation": true
},
"Math 2": {
"Geometry": true
}
}
Run Code Online (Sandbox Code Playgroud)
关于这种方法的一个有趣的事情是它非常快.请注意,它只能通过输入数组进行一次传递,这与需要多次传递的其他解决方案不同(无论您是自己编写还是_.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 );
Run Code Online (Sandbox Code Playgroud)
这将记录:
[
{
"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"
}
]
Run Code Online (Sandbox Code Playgroud)
Rai在评论中询问这行代码是如何工作的:
var grade = grades[item.Grade] = grades[item.Grade] || {};
Run Code Online (Sandbox Code Playgroud)
这是获取对象属性或在缺少属性时提供默认值的常用习惯用法.请注意,=分配按从右到左的顺序完成.所以我们可以将它翻译为使用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;
Run Code Online (Sandbox Code Playgroud)
您可能会注意到,在grades[item.Grade]已经存在的情况下,我们获取刚刚获取的值并将其存储回相同的属性中.当然,这是不必要的,如果你像这样编写代码,你可能不会这样做.相反,你会简化它:
var grade = grades[item.Grade];
if( ! grade ) {
grade = grades[item.Grade] = {};
}
Run Code Online (Sandbox Code Playgroud)
这是编写相同代码的完美合理方式,而且效率也更高.它还为您提供了一种比||成语所依赖的"真实性"更具体的测试方法.例如,if( ! grade )您可能不想使用if( grade === undefined ).
小智 13
我知道已经有很多答案,但对我来说最复杂的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);Run Code Online (Sandbox Code Playgroud)
您可以直接尝试使用Chrome浏览器控制台并根据需要进行编辑.
我希望这可以帮助别人.
Nom*_*aed 10
我需要对 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);
Run Code Online (Sandbox Code Playgroud)
复兴一个老问题,但我想在@ 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
Run Code Online (Sandbox Code Playgroud)
针对您的案例的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;
}
Run Code Online (Sandbox Code Playgroud)
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))Run Code Online (Sandbox Code Playgroud)
这是一种更简单的实用方法
standardsList = standardsList.filter((li, idx, self) => self.map(itm => iem.Grade+itm.domain).indexOf(li.Grade+li.domain) === idx)
Run Code Online (Sandbox Code Playgroud)
小智 5
**以下方法可以按照您想要的方式进行。它根据所有属性值过滤数组。**
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)
Run Code Online (Sandbox Code Playgroud)
结果这个
[{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"}]
Run Code Online (Sandbox Code Playgroud)