Javascript:使用键从数组中查找重复值

Javascript: Find douplicated values from array with keys

标题几乎不言自明...

我希望能够从 JavaScript 数组中找到重复的值。

数组键可以重复,所以我只需要验证数组值。

这是一个例子:

var arr=[
    Ibanez:     'JoeSatriani',
    Ibanez:     'SteveVai',
    Fender:     'YngwieMalmsteen',
    Fender:     'EricJohnson',
    Gibson:     'EricJohnson',
    Takamine:   'SteveVai'
];

在那个例子中:

关键是吉他品牌 该值是吉他手的名字。

所以:

如果在当前示例中存在重复键(例如:IbanezFender),那没问题:-)

但是

如果存在重复值(如:EricJohnsonSteveVai),我希望得到 (return) 错误:

EricJohnson,SteveVai

Javascript 中不能有关联数组。您可以创建一个对象数组,例如:

var arr=[
    {Ibanez:     'JoeSatriani'},
    {Ibanez:     'SteveVai'},
    {Fender:     'YngwieMalmsteen'},
    {Fender:     'EricJohnson'},
    {Gibson:     'EricJohnson'},
    {Takamine:   'SteveVai'}
];

然后你需要一个 for...in 循环来遍历数组中的每个对象,创建一个新的值数组并检查 that 是否重复,这是也不是很简单 - 基本上你需要对数组进行排序并确保没有值与它后面的值相同。

var arrayOfValues = [];

arr.forEach(function(obj){
    for(var prop in obj)
        arrayOfValues.push(obj[prop]);
});

arrayOfValues.sort(); // by default it will sort them alphabetically

arrayOfValues.forEach(function(element,index,array){
   if(array[index+1] && element==array[index+1])
     alert("Duplicate value found!");
});

首先对象键不能重复

这意味着:

({
    "Fender": "Jim",
    "Fender": "Bob"
})["Fender"]

只需 return: "Bob".

但是,我确实编写了一个代码,可以让您在值中找到重复项,但正如我所说,密钥必须是唯一的:

var arr = {
    Ibanez: 'EricJohnson',
    Fender: 'YngwieMalmsteen',
    Gibson: 'EricJohnson',
    Takamine: 'SteveVai',
    "Takamine2": 'SteveVai'
};

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

var track = [];
var exists = [];
for (var val in arr) {

    if (contains(track, arr[val])) {
        exists.push(arr[val]);
    } else {
        track.push(arr[val])
    }
}

alert(exists)

你可以看到它在这里工作:http://jsfiddle.net/dr09sga6/2/

正如其他人评论的那样,您提供的示例数组不是有效的 JavaScript 数组。但是,您可以为每种吉他类型保留一个列表:

var mapping = {
    Ibanez:     ['JoeSatriani','SteveVai'],
    Fender:     ['YngwieMalmsteen','EricJohnson']
    Gibson:     ['EricJohnson'],
    Takamine:   ['SteveVai']
];

或每个 guitar/musician 对的列表:

var pairs = [
    ['Ibanez','JoeSatriani'],
    ['Ibanez','SteveVai'],
    ['Fender','YngwieMalmsteen'],
    ['Fender','EricJohnson'],
    ['Gibson','EricJohnson'],
    ['Takamine','SteveVai']
];

您的解决方案将取决于您使用的模式。然而,在第二种情况下,它可以在一个链式函数调用中完成:

pairs.map(function(e) {return e[1]})  // Discard the brand names
.sort()  // Sort by artist
.reduce(function(p,c,i,a){
  if (i>0 && a[i]==a[i-1] && !p.some(function(v) {return v == c;})) p.push(c);
  return p;
},[]);  //Return the artist names that are duplicated

http://jsfiddle.net/mkurqmqd/1/

为了打破 reduce 回调,这里再次回调:

function(p,c,i,a){
      if (i>0 
          && a[i]==a[i-1] 
          && !p.some(function(v) {
             return v == c;
          })) 
            p.push(c);
      return p;
}

reduce 将为数组中的每个元素调用回调,并将每次调用的返回值作为第一个参数 (p) 传递给下一次调用。它对于在数组中移动时累积列表很有用。

因为我们正在回顾上一个项目,所以我们需要确保我们没有超出项目 0 的范围。

然后我们检查此项是否与(排序的)列表中的前一项匹配。

然后我们检查(使用 Array.prototype.some())我们找到的值是否已经在我们的重复项列表中...以避免出现重复项!

如果所有这些检查都通过,我们会将名称添加到重复值列表中。