如何在javascript中从数组中删除重复项
我已经为一个好的搜索设置了一个通用的标题,但是我的问题更具体一些 我有一个数组:如何在javascript中从数组中删除重复项,javascript,arrays,Javascript,Arrays,我已经为一个好的搜索设置了一个通用的标题,但是我的问题更具体一些 我有一个数组: var keywords= ["Anglo-Saxon English","American English","British English","Canadian English","Fast British English","Austrian German","American Football","British English","Fast British English","Blue Jeep","H
var keywords= ["Anglo-Saxon English","American English","British English","Canadian English","Fast British English","Austrian German","American Football","British English","Fast British English","Blue Jeep","Hot Summer","Mild Summer","Hot Brazilian Summer"];
和另一个阵列:
var terms = ["english","english","english","english","english","german","football","british english","british english","jeep","summer","summer","summer"];
每个关键字都对应于每个术语,因为每个关键字本身都包含相应的术语。例如,“Anglo-Saxon English”关键字对应“English”术语,“American Football”关键字对应“Football”术语等。但是,在关键字数组中存在一些重复项。在本例中,重复的关键字为:对应于“英语”术语和“英国英语”术语的“英国英语”关键字;对应于“英语”术语和“英国英语”术语的“快速英国英语”关键字。可以有任意数量的副本(为了简单起见,我放了2个)。所有关键字在数组中的顺序都相同,因此两个数组的长度相同
我的问题是如何在副本中只留下一个元素,其中有更具体的对应术语?例如,“british english”比“english”更具体,因此我想从两个数组中删除“british english”(关键字[2])及其各自的术语“english”(术语[2])的重复关键字,并只保留“british english”(关键字[7])及其术语“british english”(术语[7])
更新:根据下面Tobos提供的解决方案,我想出了一把工作小提琴,它是:。然而,这里的“快速英式英语”和“英式英语”仍然被“语言”所接受,而不是被“汽车”类别所接受,后者有更具体的“英式英语”术语,而不仅仅是“语言”类别中的“英语”术语。有什么想法吗?原始数组:[1,3,2,1,4,5,6,4,3,5,6,2,3,4,1,4,6,4,10,3,10,“a”,“a”] 删除重复项:[1,10,2,3,4,5,6,“a”]
原始数组:[1,3,2,1,4,5,6,4,3,5,6,2,3,4,1,4,6,4,10,3,10,“a”,“a”] 删除重复项:[1,10,2,3,4,5,6,“a”]
让项目在不同的数组中依赖于彼此的顺序通常是个坏主意,因为维护起来非常困难。我建议对您的数据使用不同的结构:
var data= [
{ keyword : "Anglo-Saxon English", term : 'english', category : 'Language' },
{ keyword : "American English", term : 'english', category : 'Language' },
{ keyword : "Fast British English", term : 'english', category : 'Sport' },
{ keyword : "British English", term : 'english', category : 'Language' },
{ keyword : "British English", term : 'british english', category : 'Language' },
{ keyword : "Fast British English", term : 'british english', category : 'Sport' },
{ keyword : "Canadian English", term : 'french', category : 'Sport' }
];
由于您的最终数据包含唯一的关键字,我将使用另一种数据结构来保存它:
预期产出:
var uniques = {
"American English": "english"
"Anglo-Saxon English": "english"
"British English": "british english"
"Canadian English": "french"
"Fast British English": "british english"
}
var uniques = {};
data.forEach(function(item){
if (isMoreSpecific(item.term, uniques[item.keyword])) {
uniques [item.keyword] = item.term;
}
});
function isMoreSpecific(term, reference) {
return !reference || term.indexOf(reference) !== -1;
}
从输入到预期输出的一些方法:
var uniques = {
"American English": "english"
"Anglo-Saxon English": "english"
"British English": "british english"
"Canadian English": "french"
"Fast British English": "british english"
}
var uniques = {};
data.forEach(function(item){
if (isMoreSpecific(item.term, uniques[item.keyword])) {
uniques [item.keyword] = item.term;
}
});
function isMoreSpecific(term, reference) {
return !reference || term.indexOf(reference) !== -1;
}
如果您不同意我的定义,或者您的定义特殊性的逻辑发生了变化,那么您显然可以更改ismore-specific
函数。您甚至可以将其内联,不过为了清晰起见,我更喜欢该函数
注意:上面的解决方案可以很容易地调整为使用您最初使用的两个阵列。只需在一个数组上使用for循环来构建
uniques
对象,然后从中重建数组
使用关键字包含类别的解决方案:
var uniques = {};
data.forEach(function(item){
var serialized = JSON.stringify({key:item.keyword, cat:item.category});
if (isMoreSpecific(item.term, uniques[serialized])) {
uniques [serialized] = item.term;
}
});
var keywordcategory = {};
for (var serialized in uniques) {
var obj = JSON.parse(serialized);
keywordcategory[obj.key] = obj.cat;
}
演示:
如果可以假定同一关键字仅在一个类别中,则无需序列化:
var uniques = {};
data.forEach(function(item){
if (isMoreSpecific(item.term, uniques[item.keyword].term)) {
uniques [item.keyword] = { term : item.term; category : item.category };
}
});
// you can now remove the unnecessary term information from the uniques map and keep just the category:
for (var key in uniques) {
uniques[key] = uniques[key].category;
}
让项目在不同的数组中依赖于彼此的顺序通常是个坏主意,因为维护起来非常困难。我建议对您的数据使用不同的结构:
var data= [
{ keyword : "Anglo-Saxon English", term : 'english', category : 'Language' },
{ keyword : "American English", term : 'english', category : 'Language' },
{ keyword : "Fast British English", term : 'english', category : 'Sport' },
{ keyword : "British English", term : 'english', category : 'Language' },
{ keyword : "British English", term : 'british english', category : 'Language' },
{ keyword : "Fast British English", term : 'british english', category : 'Sport' },
{ keyword : "Canadian English", term : 'french', category : 'Sport' }
];
由于您的最终数据包含唯一的关键字,我将使用另一种数据结构来保存它:
预期产出:
var uniques = {
"American English": "english"
"Anglo-Saxon English": "english"
"British English": "british english"
"Canadian English": "french"
"Fast British English": "british english"
}
var uniques = {};
data.forEach(function(item){
if (isMoreSpecific(item.term, uniques[item.keyword])) {
uniques [item.keyword] = item.term;
}
});
function isMoreSpecific(term, reference) {
return !reference || term.indexOf(reference) !== -1;
}
从输入到预期输出的一些方法:
var uniques = {
"American English": "english"
"Anglo-Saxon English": "english"
"British English": "british english"
"Canadian English": "french"
"Fast British English": "british english"
}
var uniques = {};
data.forEach(function(item){
if (isMoreSpecific(item.term, uniques[item.keyword])) {
uniques [item.keyword] = item.term;
}
});
function isMoreSpecific(term, reference) {
return !reference || term.indexOf(reference) !== -1;
}
如果您不同意我的定义,或者您的定义特殊性的逻辑发生了变化,那么您显然可以更改ismore-specific
函数。您甚至可以将其内联,不过为了清晰起见,我更喜欢该函数
注意:上面的解决方案可以很容易地调整为使用您最初使用的两个阵列。只需在一个数组上使用for循环来构建
uniques
对象,然后从中重建数组
使用关键字包含类别的解决方案:
var uniques = {};
data.forEach(function(item){
var serialized = JSON.stringify({key:item.keyword, cat:item.category});
if (isMoreSpecific(item.term, uniques[serialized])) {
uniques [serialized] = item.term;
}
});
var keywordcategory = {};
for (var serialized in uniques) {
var obj = JSON.parse(serialized);
keywordcategory[obj.key] = obj.cat;
}
演示:
如果可以假定同一关键字仅在一个类别中,则无需序列化:
var uniques = {};
data.forEach(function(item){
if (isMoreSpecific(item.term, uniques[item.keyword].term)) {
uniques [item.keyword] = { term : item.term; category : item.category };
}
});
// you can now remove the unnecessary term information from the uniques map and keep just the category:
for (var key in uniques) {
uniques[key] = uniques[key].category;
}
我不确定我是否理解正确,但仍然 让我们从这个小函数开始:
function removeLessSpecific(ary) {
return ary.filter(function(x) {
return !ary.some(function(y) {
return x != y && y.indexOf(x) >= 0;
});
});
}
当应用于说
["american football","english","british english","football","german"]
它只返回更具体或“独立”的术语
现在,让我们将数组转换为映射结构:
mapping = {}
keywords.forEach(function(kw, i) {
mapping[kw] = (mapping[kw] || []);
mapping[kw].push(terms[i]);
})
映射将如下所示:
{
"Anglo-Saxon English":["english"],
"American English":["english"],
"British English":["english","british english"], etc
最后,迭代映射,删除不太特定的关键字并填充新数组:
newTerms = [], newKw = []
Object.keys(mapping).forEach(function(term) {
var kwords = mapping[term];
removeLessSpecific(kwords).forEach(function(kw) {
newTerms.push(term);
newKw.push(kw);
})
})
顺便说一句,我觉得你的名字有点混乱。在您的示例中,第一个数组必须是“terms”(=专有名称),第二个数组必须是“keywords”。我不确定我是否理解正确,但仍然 让我们从这个小函数开始:
function removeLessSpecific(ary) {
return ary.filter(function(x) {
return !ary.some(function(y) {
return x != y && y.indexOf(x) >= 0;
});
});
}
当应用于说
["american football","english","british english","football","german"]
它只返回更具体或“独立”的术语
现在,让我们将数组转换为映射结构:
mapping = {}
keywords.forEach(function(kw, i) {
mapping[kw] = (mapping[kw] || []);
mapping[kw].push(terms[i]);
})
映射将如下所示:
{
"Anglo-Saxon English":["english"],
"American English":["english"],
"British English":["english","british english"], etc
最后,迭代映射,删除不太特定的关键字并填充新数组:
newTerms = [], newKw = []
Object.keys(mapping).forEach(function(term) {
var kwords = mapping[term];
removeLessSpecific(kwords).forEach(function(kw) {
newTerms.push(term);
newKw.push(kw);
})
})
顺便说一句,我觉得你的名字有点混乱。在您的示例中,第一个数组必须是“术语”(=专有名称),第二个数组必须是“关键字”。正如Tibos所说,您需要重新构造数据。有两个数组是不好的
var data = [
{keyword: "Anglo-Saxon English", term: 'english'},
{keyword: "British English", term: 'english'},
{keyword: "British English", term: 'british english'},
{keyword: "Fast British English", term: 'british english'},
{keyword: "Canadian English", term: 'french'}
];
添加唯一的数据数组:
var uniqueData = [];
步骤1-将所有关键字提取到uniqueKeywords
数组中
var uniqueKeywords = [];
data.forEach(function(item) {
//if keyword doesn't already exist, push it
if (uniqueKeywords.indexOf(item.keyword) === -1)
uniqueKeywords.push(item.keyword);
});
步骤2-对于每个关键字,找到所有对应的数据对象,只将最相关的一个添加到uniqueData
var extractMostRelevant = function(array){
var mostRelevant = array[0];
array.forEach(function(item){
if(item !== array[0]){
if(item.term.length > mostRelevant.term.length)
mostRelevant = item;
}
});
return mostRelevant;
};
uniqueKeywords.forEach(function(keyword){
var itemsWithCurrentKeyword = [];
data.forEach(function(item){
if(keyword === item.keyword)
itemsWithCurrentKeyword.push(item);
});
var mostRelevant = extractMostRelevant(itemsWithCurrentKeyword);
uniqueData.push(mostRelevant);
});
现在,您有了两个数组:
data
,和uniqueData
,正如Tibos所说,您需要重新构造数据。有两个数组是不好的
var data = [
{keyword: "Anglo-Saxon English", term: 'english'},
{keyword: "British English", term: 'english'},
{keyword: "British English", term: 'british english'},
{keyword: "Fast British English", term: 'british english'},
{keyword: "Canadian English", term: 'french'}
];
添加唯一的数据数组:
var uniqueData = [];
步骤1-将所有关键字提取到uniqueKeywords
数组中
var uniqueKeywords = [];
data.forEach(function(item) {
//if keyword doesn't already exist, push it
if (uniqueKeywords.indexOf(item.keyword) === -1)
uniqueKeywords.push(item.keyword);
});
步骤2-对于每个关键字,找到所有对应的数据对象,只将最相关的一个添加到uniqueData
var extractMostRelevant = function(array){
var mostRelevant = array[0];
array.forEach(function(item){
if(item !== array[0]){
if(item.term.length > mostRelevant.term.length)
mostRelevant = item;
}
});
return mostRelevant;
};
uniqueKeywords.forEach(function(keyword){
var itemsWithCurrentKeyword = [];
data.forEach(function(item){
if(keyword === item.keyword)
itemsWithCurrentKeyword.push(item);
});
var mostRelevant = extractMostRelevant(itemsWithCurrentKeyword);
uniqueData.push(mostRelevant);
});
好了