我有一系列点(lat-long坐标),其中一些是重复的。对于重复项,重复项将在数组中重复四次。我想知道数组中重复项的第一次和最后一次出现的索引。到目前为止,这就是我所做的:
我正在检查每个元素旁边的元素(这是一个未排序的数组)
for(var i = 0; i < points.length; i++) {
for(var j=i+1; j<points.length; j++) {
if(points[i] == points[j]) {
var firstOccurrence = points.indexOf(points[i]);
var lastOccurrence = points.indexOf(points[i], j+1);
console.log(firstOccurrence);
console.log(lastOccurrence);
}
}
}
firstOccurrence正确地给出了重复的第一次出现的索引,但是打印了相同的索引四次(可以循环遍历for循环?)。 lastOccurrence也正确打印,但是第一次打印正确的索引和&#34; -1&#34;剩下的三次。我在这做什么错?我对javascript相对较新。
编辑: 如果我做了
if(firstOccurrence) {
console.log(firstOccurrence); //I would do something else here too apart from printing
}
它首先出现第一个副本并打印剩余的索引。例如,如果我的数组是:
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?
答案 0 :(得分:3)
查找重复项的有效方法 - 无需遍历每个元素的数组 - 就是找到一种方法来散列坐标。然后,您可以使用reducer对每个数组的所有索引进行分组,并轻松找到重复的坐标。
例如,假设您的数据如下所示:
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;
}, {});
现在你有一个对象,它包含你的键值对的所有元素,以及它们在原始和未更改的数组中的索引。
编辑:在减少功能中,我在acc。
中使用了d而不是键答案 1 :(得分:0)
以下是我的两个版本的解决方案: 第一个版本很容易理解,但它会重复打印4次。 第二个版本使用@Jonah Williams提出的map reduce
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);
简单版本输出:(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)
Map reduce版本输出: (0,6),(7,13),(14,20)