如何在数组中返回重复字符串数组?

时间:2013-08-16 18:31:40

标签: javascript arrays duplicates unique underscore.js

我需要一个接收数组的函数,并返回一个包含所有重复项的数组。如果可能,我更愿意使用 underscore

给出数组:

[
    "apple",
    "apple",
    "pear",
    "pear",
    "kiwi",
    "peach"
]

我需要返回一个数组

[
    "apple",
    "pear"
]

我发现的许多方法都会返回一个布尔值而不是重复数组。

例如

var fruits = ["apple","apple"];
var uniq_fruits = _.uniq(fruits);
var duplicates_exist = (fruits.length == uniq_fruits.length);

7 个答案:

答案 0 :(得分:5)

您可以使用_.countBy来获取单词频率,然后使用_.reduce收集频率大于1的值:

function collect_dups(a, n, word) {
    if(n > 1)
        a.push(word);
    return a;
}
var dups = _(words).chain()
                   .countBy()
                   .reduce(collect_dups, [])
                   .value();

演示:http://jsfiddle.net/ambiguous/gKmfh/1/

答案 1 :(得分:3)

将您的列表转换为地图,然后将地图转换为列表。

var fruits = ["apple", // ... ];

function fruitCounter(countMap, fruit) {
  if (countMap[fruit] == null)
    countMap[fruit] = 1;
  else
    countMap[fruit]++;
  return countMap;
}

function dupFinder(dupList, count, fruit) {
  if (count > 1)
    dupList.push(fruit);
  return dupList;
}

var dups = _.reduce(_.reduce(fruits, fruitCounter, {}), dupFinder, []);

有点不幸的是,对于对象的属性来说,没有什么真的像“过滤器”,但是对于“reduce”来说并不是太糟糕。

编辑 - 来自Underscore的人的评论比我指出的内部“减少”可以用更简单的“countBy”代替:

var dups = _.reduce(_.countBy(fruits, function(f) { return f; }), dupFinder, []);

答案 2 :(得分:1)

var common = function(array){

    var tally = function(array){
        var make_object = {};
        _.each(array, function(item){
            make_object[item] = (typeof make_object[item] == "undefined") ? 1 : make_object[item] + 1;
        });
        return make_object;        
    }(array);

    var duplicates = function(obj){
        var duplicates = [];
        _.each(obj, function(value, key){
            if(value > 1){
                duplicates.push(key);
            }
        });
        return duplicates;
    }(tally);

    return duplicates;

};

答案 3 :(得分:1)

这个想法很直接。按项目对项目进行分组,然后找到包含多个项目的组。最后只从每组中挑选一个项目。

lst = [ "apple", "apple", "pear", "pear", "kiwi", "peach"];
var result = _.chain(lst)
    .groupBy(function (i) { return i; })
    .filter(function (v, k) { return v.length > 1; })
    .map(function(v){return v[0]; })
    .value();

>>["apple", "pear"] 

答案 4 :(得分:1)

其中arr是您的输入,您只需检查该元素是否是obj对象上的键 - 如果是,则将其传递给输出数组并重新循环,否则将键添加到对象:

function findDupes(arr) {
  var obj = {}, newArr = [];
  for (var i = 0, l = arr.length; i < l; i++) {
    if (obj[arr[i]]) { newArr.push(arr[i]); continue; }
    obj[arr[i]] = true;
  }
  return newArr;
}

var dupes = findDupes(arr);

答案 5 :(得分:0)

给你一个简单的一级字符串数组,我建议先对数组进行排序,然后循环遍历它,尝试将当前项与下一项进行比较。 像这样:

var fruit = [
    "apple",
    "apple",
    "apple",
    "pear",
    "pear",
    "cantalope"
];

var common = function(array){
    var mySortedArray = array.sort();
    var myResultArray = [];

    for (var i = 0; i < mySortedArray.length - 1; i++)
      if ( (mySortedArray[i + 1] == mySortedArray[i]) && 
        (mySortedArray[i] != myResultArray[myResultArray.length-1]) )
        myResultArray.push(mySortedArray[i]);

    return myResultArray;
};

alert(common(fruit));

答案 6 :(得分:0)

我从这个函数开始:https://stackoverflow.com/a/840849/1636522

function getDuplicates(arr) {
    var i,
        len = arr.length,
        out = [],
        obj = {};
    for (i = 0; i < len; i++) {
        switch (obj[arr[i]]) {
            case undefined: obj[arr[i]] = 1; break;
            case 1: obj[arr[i]] = 2; out.push(arr[i]); break;
        }
    }
    return out;
}