【问题标题】:How do I return array of duplicate strings in array?如何在数组中返回重复字符串的数组?
【发布时间】:2013-08-19 06:02:28
【问题描述】:

我需要一个接收数组并返回包含所有重复项的数组的函数。如果可能,我更愿意使用 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);

【问题讨论】:

  • 如果你没有电脑,你会怎么做?
  • @Pointy 传送带和颜色识别?
  • 所以如果我在一张纸上写下水果名称列表,您需要传送带来查找重复项吗?难道没有更简单的方法来处理水果名称列表吗?比如,有没有什么方法可以记录你看到的每个名字?
  • @Pointy 不知道你要去哪里。不过,我非常感谢您的时间、努力和耐心。我没有机会与许多编码人员交谈,而且我不喜欢重新发明轮子,我假设有一种简单的方法可以使用下划线完成这项工作,并且可能没有.sort()

标签: javascript arrays duplicates unique underscore.js


【解决方案1】:

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

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));

【讨论】:

【解决方案2】:

将您的列表变成地图,然后将地图变成列表。

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, []);

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

edit — 比我更擅长 Underscore 的人的评论指出,内部的“reduce”可以用更简单的“countBy”代替:

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

【讨论】:

  • 你可以使用_.countBy代替内部的_.reduce
  • @muistooshort 啊好的;我几乎不知道下划线:)
  • 您也可以将“function(f) { return f; }”替换为_.identity
  • @ne8il 哦,酷。我从来没有用 Underscore 做过很多认真的工作,但我用过 Functional,它有一个类似的“我”身份功能。
  • 您也可以使用_.chain 来避免嵌套的_.X 调用(见下文)。
【解决方案3】:
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;

};

【讨论】:

    【解决方案4】:

    您可以使用_.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/

    【讨论】:

    • 这显然是真正地道的下划线答案:)
    【解决方案5】:

    这个想法非常简单。按项目的值对项目进行分组,然后找出哪个组有超过 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"] 
    

    【讨论】:

      【解决方案6】:

      其中 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);

      【讨论】:

      • 对于它的价值,Thomas,@Pointy 所说的,他和我展示的,是 Javascript 对象有一个很棒的地方——它们的键是独一无二的。这意味着您可以将事物分配给它们并进行简单的测试以查看它们是否存在。与先将整个数组转换为对象(地图)的 Pointy 不同,您可以按照我上面描述的 FWIW 即时执行此操作,虽然我喜欢下划线来进行大量繁重的工作,但 IMO 这样做更容易。跨度>
      • 如果重复两次以上,这会将同一项目多次推送到结果中。
      【解决方案7】:

      我从这个函数开始: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;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-02-15
        • 1970-01-01
        • 2011-07-27
        • 2018-02-17
        • 2020-07-14
        • 2013-02-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多