0

我需要一个接收数组并返回包含所有重复项的数组的函数。如果可能的话,我更喜欢使用下划线

给定数组:

[
    "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);
4

7 回答 7

5

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

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/

于 2013-08-16T19:26:50.737 回答
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, []);

有点不幸的是,对于对象的属性没有什么真正类似于“过滤器”的东西,但使用“减少”并不算太糟糕。

编辑——一个比我更擅长下划线的人的评论指出,内部的“减少”可以用更简单的“countBy”代替:

var dups = _.reduce(_.countBy(fruits, function(f) { return f; }), dupFinder, []);
于 2013-08-16T19:15:00.923 回答
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);

于 2013-08-17T00:11:08.570 回答
1

这个想法非常简单。按项目的值对项目进行分组,然后找出哪个组有超过 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"] 
于 2013-08-16T23:52:42.650 回答
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;

};
于 2013-08-16T19:18:48.103 回答
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));
于 2013-08-16T18:45:34.967 回答
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;
}
于 2013-09-09T05:30:01.320 回答