Javascript:使用键从数组中查找重复值
Javascript: Find douplicated values from array with keys
标题几乎不言自明...
我希望能够从 JavaScript 数组中找到重复的值。
数组键可以重复,所以我只需要验证数组值。
这是一个例子:
var arr=[
Ibanez: 'JoeSatriani',
Ibanez: 'SteveVai',
Fender: 'YngwieMalmsteen',
Fender: 'EricJohnson',
Gibson: 'EricJohnson',
Takamine: 'SteveVai'
];
在那个例子中:
关键是吉他品牌
该值是吉他手的名字。
所以:
如果在当前示例中存在重复键(例如:Ibanez
或 Fender
),那没问题:-)
但是
如果存在重复值(如:EricJohnson
或 SteveVai
),我希望得到 (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()
)我们找到的值是否已经在我们的重复项列表中...以避免出现重复项!
如果所有这些检查都通过,我们会将名称添加到重复值列表中。
标题几乎不言自明...
我希望能够从 JavaScript 数组中找到重复的值。
数组键可以重复,所以我只需要验证数组值。
这是一个例子:
var arr=[
Ibanez: 'JoeSatriani',
Ibanez: 'SteveVai',
Fender: 'YngwieMalmsteen',
Fender: 'EricJohnson',
Gibson: 'EricJohnson',
Takamine: 'SteveVai'
];
在那个例子中:
关键是吉他品牌 该值是吉他手的名字。
所以:
如果在当前示例中存在重复键(例如:Ibanez
或 Fender
),那没问题:-)
但是
如果存在重复值(如:EricJohnson
或 SteveVai
),我希望得到 (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()
)我们找到的值是否已经在我们的重复项列表中...以避免出现重复项!
如果所有这些检查都通过,我们会将名称添加到重复值列表中。