如何在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);
});
好了