【问题标题】:Rename duplicates in an array JavaScript重命名数组 JavaScript 中的重复项
【发布时间】:2017-07-29 01:58:15
【问题描述】:

我正在寻求帮助以解决重命名数组中的字符串的问题,如下所示:

["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"]

函数执行后应该如下所示:

["a(1)","a(6)","a","a(2)","a(3)","a(4)","a(5)","a(7)","a(8)","a(9)","a(10)","a(11)"]

空数组和没有重复的数组应该保持不变。

我的想法是用键/值对填充一个空对象,然后将它们推送到一个新数组:

function renameFiles(arr){
    var itemsObj = {};
    var count = 1;
    for (var i = 0; i < arr.length; i++){

        itemsObj[arr[i]] = count;
        // if the key present, rename the array item and add it to the 
        // itemsObj
        if (arr[i] in itemsObj){
            itemsObj[arr[i] + '(' + (i - (i - 1)) + ')']
        }

    }
    console.log(itemsObj)
    // once the itmesObj is set, run the loop and push the keys to the 
    // array
    return arr;

}

var array = ["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"]
renameFiles(array);

问题是itemsObj 没有填充重复键。应该有其他方法可以处理此任务。我是初学者,可能不知道这种方法。

【问题讨论】:

    标签: javascript arrays string object rename


    【解决方案1】:

    你快到了。你会保持计数,检查重复项,然后用括号再次检查重复项,并适当更新计数

    function renameFiles(arr){
      var count = {};
      arr.forEach(function(x,i) {
    
        if ( arr.indexOf(x) !== i ) {
          var c = x in count ? count[x] = count[x] + 1 : count[x] = 1;
          var j = c + 1;
          var k = x + '(' + j + ')';
    
          while( arr.indexOf(k) !== -1 ) k = x + '(' + (++j) + ')';
          arr[i] = k;
        }
      });
      return arr;
    }
    
    var res = renameFiles(["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"]);
    console.log(res)
    .as-console-wrapper {top:0; max-height:100%!important}

    【讨论】:

    • 嗯。你每天学习新的东西。不知道您可以在三元运算符内递增。
    • @Skam - 你可以很好地增加,但依赖分配的结果,就像我在上面所做的那样,在很多情况下应该避免,至少在我看来。我在这里这样做是为了避免整个if/else 混乱检查密钥等,我认为这很好,因为这样做不应该有任何问题在这种特定情况下
    • @adeneo 请你解释一下这行var c = x in count ? count[x] = count[x] + 1 : count[x] = 1;这种风格我还不熟悉。
    • 当然,如果xcount 中,则执行count[x] = count[x] + 1,这只会将计数加一,否则如果x 不在count 中,则将其设置为@987654330 @。由于分配总是返回分配的值,所以我得到了c 中设置的任何内容,即当前计数。
    • @adeno 谢谢先生!!你的帮助很大。
    【解决方案2】:

    你在正确的轨道上。

    另一种解决方案,

    (function(){
        var renameFiles = function(arr){
            var counts = {}
            for(var i=0;i<arr.length;i++){
                if(!counts[arr[i]])
                    counts[arr[i]]=0;
                counts[arr[i]]++;
            }
            arr = [];
            for(var name in counts){
                for(var i=0;i<counts[name];i++){
                    arr.push(name+(i===0?'':'('+i+')'));
                }
            }
            return arr;
        }
    
        var array = ["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"];
        console.log(renameFiles(array))
    })();
    

    【讨论】:

      【解决方案3】:
      var arr = ["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"]
      
      function renameFiles(arr){
        var dup_count, new_name;
        arr.forEach((item, index) => {
          dup_count = arr.filter(x => x == item).length;
          if (dup_count > 1) {
            for(n = 0; n < dup_count;){
              do {
                new_name = `${item}(${n+=1})`;
              } while (arr.includes(new_name));
              arr[arr.indexOf(item)] = new_name;
            }
          }
        });
        return arr
      }
      > renameFiles(arr)
      < (12) ["a(1)", "a(6)", "a(2)", "a(3)", "a(4)", "a(5)", "a(7)", "a(8)", "a(9)", "a(10)", "a(11)", "a"]
      

      【讨论】:

        【解决方案4】:

        要在没有突变的情况下获得相同的结果,您可以使用以下代码。虽然代码更多,但我包含的大多数函数都可以替换为 Ramda 或其他 FP 库中包含的函数。我发现以下内容更具可读性,但这只是个人喜好问题。

        工作沙盒here.

        const incrementingList = (n) => [...Array(n).keys()];
        const formatStr = (key) => ifElse(equals(0))(always(key))(concat(key));
        
        const incValues = (obj) =>
          flatMap((key) => map(formatStr(key))(incrementingList(obj[key])))(keys(obj));
        
        const incOrInit = (record, key) =>
          isNil(record[key])
            ? assoc(key)(1)(record)
            : assoc(key)(inc(record[key]))(record);
        
        const generateCounts = reduce({})(incOrInit);
        const renameList = compose(incValues, generateCounts);
        
        const list = ["a", "b", "b", "b", "a", "a", "c", "c", "c", "d"];
        const result = renameList(list);
        console.log(result); // => ["a", "a1", "a2", "b", "b1", "b2", "c", "c1", "c2", "d"]
        
        // THESE FUNCTIONS CAN BE REPLACE WITH RAMDA \\
        
        function keys(obj) {
          return Object.keys(obj);
        }
        
        function ifElse(cond) {
          return function ifTrueFn(trueFn) {
            return function ifFalseFn(falseFn) {
              return function passValue(value) {
                return cond(value) ? trueFn(value) : falseFn(value);
              };
            };
          };
        }
        
        function always(value) {
          return function alwaysInner() {
            return value;
          };
        }
        
        function concat(a) {
          return function inner(b) {
            return a.concat(b);
          };
        }
        
        function equals(a) {
          return function equalsInner(b) {
            return a === b;
          };
        }
        
        function compose2(fn1, fn2) {
          return function passArg(...args) {
            return fn1(fn2(...args));
          };
        }
        
        function compose(...fns) {
          return fns.reduce(compose2);
        }
        
        function flatMap(mapFn) {
          return function inner(list) {
            return list.flatMap(mapFn);
          };
        }
        
        function map(mapFn) {
          return function passList(list) {
            return list.map(mapFn);
          };
        }
        
        function reduce(init) {
          return function reducer(reducer) {
            return function data(data) {
              return data.reduce(reducer, init);
            };
          };
        }
        
        function assoc(key) {
          return function assocValue(value) {
            return function assocObject(obj) {
              return { ...obj, [key]: value };
            };
          };
        }
        
        function inc(n) {
          return n + 1;
        }
        
        function isNil(value) {
          return value == null;
        }
        

        【讨论】:

          猜你喜欢
          • 2012-05-25
          • 1970-01-01
          • 1970-01-01
          • 2018-03-04
          • 2021-04-17
          • 2013-07-31
          • 1970-01-01
          • 2013-08-03
          • 1970-01-01
          相关资源
          最近更新 更多