【问题标题】:Create an array of sub-arrays with the value of an element and the number of times it has repeated in JavaScript用一个元素的值和它在 JavaScript 中重复的次数创建一个子数组数组
【发布时间】:2015-08-29 13:17:27
【问题描述】:

我正在尝试获取一个数组(例如,一个年份数组),然后制作一个新的子数组数组,它​​首先告诉原始数组中的唯一元素,其次是多少时间它被重复了。

例如,假设我从一个数字数组开始 [1999, 1999, 2000, 2005, 2005, 2005, 2015]

我希望我的函数返回像[[1999, 2], [2000, 1], [2005, 3], [2015, 1] ]这样的数组
因为1999年重复了两次,2000年没有重复,2005年重复了3次,等等。

我可以成功创建一个删除重复项的新数组,但是在创建子数组时我遇到了一些奇怪的行为。

编辑

这是我自己的错误解决方案,以防有人想指出我做错了什么。

var populateYearsList = function(yearsDuplicate){

var uniqueYears = [];
for (var i=0; i < yearsDuplicate.length; i++){
 if(uniqueYears.indexOf(yearsDuplicate[i]) == -1){
  uniqueYears.push(yearsDuplicate[i])
} else {
  console.log("duplicate found") };
}
 console.log (uniqueYears)
};

我遇到了尝试将uniqueYears.push(yearsDuplicate[i]) 更改为uniqueYears.push([ yearsDuplicate[i], 1 ]) 然后尝试将我的console.log 替换为某种递增计数器的问题。

【问题讨论】:

  • 到目前为止你的代码是什么,奇怪的行为是什么?
  • 所以你想要一个包含五个数组的数组。像这样在新数组中推送对象怎么样-> var filteredArr = [{"year":1999, "amount": 2}, {"year":2000, "amount":1}]
  • @Rhumborl 我刚刚编辑了我的条目以展示我尝试过的奇怪解决方案。每当我尝试推送一个数组而不仅仅是年份时,我的循环就会停止工作。

标签: javascript arrays algorithm unique repeat


【解决方案1】:

我会这样做:

var input = [1999, 1999, 2000, 2005, 2005, 2005, 2015];

function numberOfOccurancesArray (input) {
    var result = {};

    for (var i = 0; i < input.length; i++) {

        var currentYear = input[i];

        // if there is an element with the name of the currentYear
        if (result[currentYear]) {

            // increace its prop `count` with 1
            result[currentYear].count += 1;

        } else {

            // if not present, create it
            result[currentYear] = {
                year: currentYear,
                count: 1
            }
        }
    }

    return result;
}

这里是示例代码:JsFiddle

【讨论】:

  • 这是我认为非常优雅的解决方案。
  • 谢谢! :) 希望对您有所帮助!
【解决方案2】:

这很简单:

var input = [1999, 1999, 2000, 2005, 2005, 2005, 2015];

var uniq = [];
input.forEach(function(n){
    if (uniq.indexOf(n)<0) 
        uniq.push(n);
});

var output = uniq.map(function(n){
    return [n, input.filter(function(m){ return m == n }).length]
});

快速解释其工作原理

给定输入数组,将其唯一版本映射到具有此映射的新数组:

element ---> [ element, 原始数组中出现的次数 ]

编辑说明:: 修复了之前可能引入重复元素的解决方案。

【讨论】:

  • 好主意,但这会为 1999 年和 2005 年创建重复条目
  • @Rhumborl 好地方。然后我相应地更新了解决方案。不再重复。
  • 感谢陶!它完美地工作!第一个uniq 部分对我来说很清楚。但是,对于解决方案的output 部分,我有点迷失了......我们正在使用map 创建一个新数组,这部分我得到了。你能解释一下input.filter(function(m){ return m == n }).length 在做什么吗?
  • @JeuelyFish 很高兴它对您有所帮助。 input.filter(function(m){ return m == n }).length 这仅从原始数组中获取等于 n 的元素。因此,给定n=1999,您将得到[1999,1999],它允许您将其计为原始数组中出现的次数。
【解决方案3】:
var years = [1999, 1999, 2000, 2005, 2005, 2005, 2015];

var occurences = [];

for(var i = 0; i < years.length; i++ ) {
    var year = years[i];
    if(typeof occurences[year] === 'undefined') {
        occurences[year] = 1;
    } else {
        occurences[year]++;   
    }
}

occurences = occurences.map(function(occurences, year) {
    return [year, occurences];
});

console.log(occurences);

编辑:更快的解决方案

    var results = [];
    var uniq = [];
    var counts = [];
    var i = 0;

    for (i; i < years.length; i++) {
        var year = years[i];
        var indexOf = uniq.indexOf(year);
        if (indexOf < 0) {
            uniq.push(year);
            counts[uniq.length - 1] = 1;
        } else {
            counts[indexOf] += 1;
        }
    }

    i = 0;

    for (i; i < uniq.length; i++) {
        results.push([uniq[i], counts[i]]);
    }

    return results;

【讨论】:

  • 我喜欢这个!但是,作为一名 jr 开发人员,您能向我解释一下 'occurences.map' 发生了什么吗?我一直遵循您的解决方案,直到那时。这是一个可行的解决方案,所以感谢您的回答和时间!
  • 好吧,我刚刚测试过了,我之前的解决方案在基准测试中确实很慢。我认为这是因为进程中生成的 Array 的长度(最后一个键索引是 2015 )。我编辑了我的帖子并发布了更快的解决方案。这是简单的基准测试:jsfiddle.net/yp8hfxgo/1
【解决方案4】:

如果您想使用函数范式,请将其简化为字典,然后将键映射到元组。

var yearToCounts = input.reduce(function(counts, year) {
    if (year in counts) {
        counts[year]++;
    } else {
        counts[year] = 1;
    }
    return counts;
}, {});

return Object.keys(yearToCounts).map(function(year) {
    return [year, yearToCounts[year]];
});

【讨论】:

  • 另外,您可以习惯性地摆脱 if : counts[year] = (counts[year] || 0)+1
猜你喜欢
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 2018-07-02
  • 2019-03-24
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
  • 2018-02-13
相关资源
最近更新 更多