Javascript获取数组中第一个和最后一个重复元素的索引
我有一个点数组(lat-long坐标),其中一些点是重复的。对于重复项,重复项将在数组中精确重复四次。我想知道数组中第一次和最后一次出现的重复项的索引。到目前为止,我所做的就是: 我正在检查每个元素及其旁边的元素(这是一个未排序的数组) 它保留第一个副本的第一个匹配项,并打印其余索引。例如,如果我的数组是:Javascript获取数组中第一个和最后一个重复元素的索引,javascript,arrays,indexing,duplicates,Javascript,Arrays,Indexing,Duplicates,我有一个点数组(lat-long坐标),其中一些点是重复的。对于重复项,重复项将在数组中精确重复四次。我想知道数组中第一次和最后一次出现的重复项的索引。到目前为止,我所做的就是: 我正在检查每个元素及其旁边的元素(这是一个未排序的数组) 它保留第一个副本的第一个匹配项,并打印其余索引。例如,如果我的数组是: points = [4,4,1,8,0,4,4,5,5,2,7,9,5,5,3,3,10,33,21,3,3]; 然后打印出来 7 14 省略第一个出现的重复项的索引,即0
points = [4,4,1,8,0,4,4,5,5,2,7,9,5,5,3,3,10,33,21,3,3];
然后打印出来
7
14
省略第一个出现的重复项的索引,即0。是因为内部for循环中的j=i+1吗?查找重复项的有效方法是找到散列坐标的方法,而不必在每个元素的数组中循环。然后,您可以使用减缩器对每个数组的所有索引进行分组,并轻松找到重复的坐标 例如,假设您的数据如下所示:
var data = [
{lat: 120, lon: 30},
{lat: 122, lon: 31},
{lat: 120, lon: 30},
...
];
// Create a function which maps each element to a hashable string
function make(d) {
return d.lat + ':' + d.lon;
}
// Create a reducer which gathers indexes
// here acc is the accumulated object which starts at {}
// d is each item in the array, and i is the index
data.reduce(function(acc, d, i) {
var key = make(d);
acc[key] = acc[key].concat(i) || [i] // gather indexes per element
return acc;
}, {});
现在,您有了一个对象,其中包含键值对的所有元素及其原始数组中的索引
编辑:在reduce函数中,我在acc中使用了d而不是键。以下是我的两个版本的解决方案: 第一个版本很容易理解,但它会将副本打印4次。 第二个版本使用了@Jonah Williams提出的map-reduce-like
function printDuplicatesSimple(points) {
var first, last;
for (var i = 0; i < points.length; i++) {
first = points.indexOf(points[i]);
last = points.lastIndexOf(points[i]);
print(duplicateToString(first, last));
}
}
function duplicateToString(first, last) {
return "(" + first + "," + last + ")";
}
function makeKey(i, arr) {
var first = points.indexOf(points[i]),
last = points.lastIndexOf(points[i]);
return first === last ? -1 : duplicateToString(first, last);
}
function printDuplicatesMapReduce(points) {
var res = points.reduce(function(dict, currentItem, index, arr) {
var key = makeKey(index, arr);
if (key === -1) {
return dict; //skip
}
if (dict.indexOf(key) === -1) {
dict.push(key);
}
return dict;
}, []);
print(res);
}
var points = [4, 4, 1, 8, 0, 4, 4, 5, 5, 2, 7, 9, 5, 5, 3, 3, 10, 33, 21, 3, 3];
printDuplicatesSimple(points);
函数PrintDuplicateSample(点){
var第一,最后;
对于(变量i=0;i
简单版本输出:(0,6)
(0,6)
(2,2)
(3,3)
(4,4)
(0,6)
(0,6)
(7,13)
(7,13)
(9,9)
(10,10)
(11,11)
(7,13)
(7,13)
(14,20)
(14,20)
(16,16)
(17,17)
(18,18)
(14,20)
(14,20)
映射减少版本输出:
(0,6),(7,13),(14,20)是否只需要一个元素的重复索引,还是数组中的每个重复元素的重复索引?我需要数组中每个重复元素的第一个和最后一个重复索引。对于ex,如果点=[4,4,1,8,0,4,4,5,5,2,7,9,5,5,3,3,10,33,21,3,3],那么我需要4,5和3的第一个和最后一个重复索引,对于4,这将是0,6-->;7,13-->表示5,14,20-->表示3。我认为我的代码应该这样做,只是我怀疑内部for循环(j)。对于每个副本,console.log将输出打印4次。可能是因为每个重复出现4次?)您的代码非常不一致,比如说您有一个[4,4,4]数组。你可以从代码中看到,它通过索引0,1打印,0,2打印,0,3等等。它应该只打印0,3。
var data = [
{lat: 120, lon: 30},
{lat: 122, lon: 31},
{lat: 120, lon: 30},
...
];
// Create a function which maps each element to a hashable string
function make(d) {
return d.lat + ':' + d.lon;
}
// Create a reducer which gathers indexes
// here acc is the accumulated object which starts at {}
// d is each item in the array, and i is the index
data.reduce(function(acc, d, i) {
var key = make(d);
acc[key] = acc[key].concat(i) || [i] // gather indexes per element
return acc;
}, {});
function printDuplicatesSimple(points) {
var first, last;
for (var i = 0; i < points.length; i++) {
first = points.indexOf(points[i]);
last = points.lastIndexOf(points[i]);
print(duplicateToString(first, last));
}
}
function duplicateToString(first, last) {
return "(" + first + "," + last + ")";
}
function makeKey(i, arr) {
var first = points.indexOf(points[i]),
last = points.lastIndexOf(points[i]);
return first === last ? -1 : duplicateToString(first, last);
}
function printDuplicatesMapReduce(points) {
var res = points.reduce(function(dict, currentItem, index, arr) {
var key = makeKey(index, arr);
if (key === -1) {
return dict; //skip
}
if (dict.indexOf(key) === -1) {
dict.push(key);
}
return dict;
}, []);
print(res);
}
var points = [4, 4, 1, 8, 0, 4, 4, 5, 5, 2, 7, 9, 5, 5, 3, 3, 10, 33, 21, 3, 3];
printDuplicatesSimple(points);