javascript中数组中重复数组的计数

javascript中数组中重复数组的计数,javascript,arrays,Javascript,Arrays,我有一个数组,如下所示: [[3, 4], [1, 2], [3, 4]] 我希望创建一个新的数组,该数组没有重复项,并且具有第一个数组中每个元素的出现次数计数: [[3,4,2], [1,2,1]] 以下是我到目前为止的情况: var alreadyAdded = 0; dataset.forEach(function(data) { From = data[0]; To = data[1]; index = 0; newDataSet.forEach(func

我有一个数组,如下所示:

    [[3, 4], [1, 2], [3, 4]]
我希望创建一个新的数组,该数组没有重复项,并且具有第一个数组中每个元素的出现次数计数:

    [[3,4,2], [1,2,1]]
以下是我到目前为止的情况:

var alreadyAdded = 0; 
dataset.forEach(function(data) {
 From = data[0];
 To = data[1];

 index = 0;
 newDataSet.forEach(function(newdata) {
  newFrom = newData[0];
  newTo = newData[1];

  // check if the point we are looking for is already added to the new array
  if ((From == newFrom) && (To == newTo)) {

   // if it is, increment the count for that pair
   var count = newData[2];
   var newCount = count + 1;
   newDataSet[index] = [newFrom, newTo, newCount];
   test = "reached here";
   alreadyAdded = 1;
  }
  index++;
 });

 // the pair was not already added to the new dataset, add it
 if (alreadyAdded == 0) {
  newDataSet.push([From, To, 1]);
 }

 // reset alreadyAdded variable
 alreadyAdded = 0;
});

我对Javascript非常陌生,有人能帮我解释一下我做错了什么吗?我确信有一种更简洁的方法可以做到这一点,但是我在javascript中找不到一个处理重复数组的示例。

修复一个拼写错误后,我在调试器中尝试了您的解决方案;它起作用了

修复了内部forEach循环变量名以匹配大小写。还添加了一些var关键字

  var alreadyAdded = 0;
  dataset.forEach(function (data) {
    var From = data[0];
    var To = data[1];

    var index = 0;
    newDataSet.forEach(function (newData) {
        var newFrom = newData[0];
        var newTo = newData[1];

        // check if the point we are looking for is already added to the new array
        if ((From == newFrom) && (To == newTo)) {

            // if it is, increment the count for that pair
            var count = newData[2];
            var newCount = count + 1;
            newDataSet[index] = [newFrom, newTo, newCount];
            test = "reached here";
            alreadyAdded = 1;
        }
        index++;
    });

    // the pair was not already added to the new dataset, add it
    if (alreadyAdded == 0) {
        newDataSet.push([From, To, 1]);
    }

    // reset alreadyAdded variable
    alreadyAdded = 0;
});

假设子数组项的顺序很重要,假设您的子数组可以是可变长度的,并且可以包含除数字以外的项,下面是解决此问题的一种相当通用的方法。目前需要ECMA5兼容性,但要使其在ECMA3上工作并不困难

Javascript

// Create shortcuts for prototype methods
var toClass = Object.prototype.toString.call.bind(Object.prototype.toString),
    aSlice = Array.prototype.slice.call.bind(Array.prototype.slice);

// A generic deepEqual defined by commonjs
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
function deepEqual(a, b) {
    if (a === b) {
        return true;
    }

    if (toClass(a) === '[object Date]' && toClass(b) === '[object Date]') {
        return a.getTime() === b.getTime();
    }

    if (toClass(a) === '[object RegExp]' && toClass(b) === '[object RegExp]') {
        return a.toString() === b.toString();
    }

    if (a && typeof a !== 'object' && b && typeof b !== 'object') {
        return a == b;
    }

    if (a.prototype !== b.prototype) {
        return false;
    }

    if (toClass(a) === '[object Arguments]') {
        if (toClass(b) !== '[object Arguments]') {
            return false;
        }

        return deepEqual(aSlice(a), aSlice(b));
    }

    var ka,
        kb,
        length,
        index,
        it;

    try {
        ka = Object.keys(a);
        kb = Object.keys(b);
    } catch (eDE) {
        return false;
    }

    length = ka.length;
    if (length !== kb.length) {
        if (Array.isArray(a) && Array.isArray(b)) {
            if (a.length !== b.length) {
                return false;
            }
        } else {
            return false;
        }
    } else {
        ka.sort();
        kb.sort();
        for (index = 0; index < length; index += 1) {
            if (ka[index] !== kb[index]) {
                return false;
            }
        }
    }

    for (index = 0; index < length; index += 1) {
        it = ka[index];
        if (!deepEqual(a[it], b[it])) {
            return false;
        }
    }

    return true;
};

// Recursive function for counting arrays as specified
// a must be an array of arrays
// dupsArray is used to keep count when recursing
function countDups(a, dupsArray) {
    dupsArray = Array.isArray(dupsArray) ? dupsArray : [];

    var copy,
        current,
        count;

    if (a.length) {
        copy = a.slice();
        current = copy.pop();
        count = 1;
        copy = copy.filter(function (item) {
            var isEqual = deepEqual(current, item);

            if (isEqual) {
                count += 1;
            }

            return !isEqual;
        });

        current.push(count);
        dupsArray.push(current);
        if (copy.length) {
            countDups(copy, dupsArray);
        }
    }

    return dupsArray;
}

var x = [
    [3, 4],
    [1, 2],
    [3, 4]
];

console.log(JSON.stringify(countDups(x)));

上,根据您迭代的数据集有多大,我会小心地循环多次。通过为原始数据集中的每个元素创建一个“索引”,然后使用它引用分组中的元素,可以避免这样做。这就是我解决问题时采取的方法。您可以在JSFIDLE上看到它。我使用
Array.prototype.reduce
创建一个对象文本,其中包含来自原始数据集的元素分组。然后我迭代它的键来创建最终的分组

var dataSet = [[3,4], [1,2], [3,4]],
    grouping = [],
    counts,
    keys,
    current;

counts = dataSet.reduce(function(acc, elem) {
    var key = elem[0] + ':' + elem[1];
    if (!acc.hasOwnProperty(key)) {
        acc[key] = {elem: elem, count: 0}
    }
    acc[key].count += 1;
    return acc;
}, {});

keys = Object.keys(counts);
for (var i = 0, l = keys.length; i < l; i++) {
    current = counts[keys[i]];
    current.elem.push(current.count);
    grouping.push(current.elem);
}

console.log(grouping);
var数据集=[[3,4]、[1,2]、[3,4]],
分组=[],
计数,
钥匙,
现在的
计数=数据集.reduce(函数(acc、elem){
var key=elem[0]+':'+elem[1];
如果(!acc.hasOwnProperty(键)){
acc[键]={elem:elem,计数:0}
}
acc[键]。计数+=1;
返回acc;
}, {});
键=对象。键(计数);
对于(变量i=0,l=keys.length;i
const x=[[3,4]、[1,2]、[3,4];
具有重复计数的常数=[
…x
.map(JSON.stringify)
.reduce((acc,v)=>acc.set(v,(acc.get(v)| | 0)+1),new Map())
.条目()
].map(([k,v])=>JSON.parse(k).concat(v));

console.log(具有重复计数)
是否将
[3,4]
[4,3]
视为相同或订单是否重要?您能否澄清您预期的结果?我不明白你是怎么得到的
[[3,4,2],[1,2,1]
它看起来不像
[3,4]
[4,3]
一样。如果查看OP代码中使用的变量,每个数组似乎只包含两个元素,第一个元素是事件前的位置,最后一个元素是事件后的位置。因此,从
3
移动到
4
与从
4
移动到
3
并不相同。谢谢科林!您的解决方案更加优雅,运行速度更快,因为数据集确实相当大。reduce函数似乎非常有用,我可能会反复使用它:)谢谢supertopi!没想到这是一个小小的打字错误!
var dataSet = [[3,4], [1,2], [3,4]],
    grouping = [],
    counts,
    keys,
    current;

counts = dataSet.reduce(function(acc, elem) {
    var key = elem[0] + ':' + elem[1];
    if (!acc.hasOwnProperty(key)) {
        acc[key] = {elem: elem, count: 0}
    }
    acc[key].count += 1;
    return acc;
}, {});

keys = Object.keys(counts);
for (var i = 0, l = keys.length; i < l; i++) {
    current = counts[keys[i]];
    current.elem.push(current.count);
    grouping.push(current.elem);
}

console.log(grouping);