最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Code Challenge: Rename filenames if duplicates are present - Stack Overflow

programmeradmin8浏览0评论

I'm working through a coding challenge I found online. I have the first test case passing but failing the second. I'm trying to decide if the second test case I'm failing is a typo or not.

Here is the question:

You are given an array of desired filenames in the order of their creation. Since two files cannot have equal names, the one which es later will have an addition to its name in a form of (k), where k is the smallest positive integer such that the obtained name is not used yet.

Return an array of names that will be given to the files.

Test Cases:

1 - Passing:

  • INPUT: ["doc", "doc", "image", "doc(1)", "doc"]
  • OUTPUT: ["doc", "doc(1)", "image", "doc(1)(1)", "doc(2)"]

2 - Failing:

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

Here is my code that passes the first Spec:

function fileNaming(names) {
    var finalArr = [],
        obj = {};
    names.forEach(function(val){

        if(obj[val] === undefined){
            if(finalArr.indexOf(val) === -1){
              finalArr.push(val);  
              obj[val] = 0;
            } else {
              obj[val] = 1;
              finalArr.push(val + "(" + obj[val] + ")" );
            }

        } else {
            finalArr.push( val + "(" + (++obj[val]) + ")");
        }
    }); 
    return finalArr;
}

Question:

  • In the second test spec, why isn't there an "a(1)(1)" like there is a "doc(1)(1)" Is this a typo?
  • If anyone has suggestions on improvining my approach or alternative approaches I would greatly appreciate your feedback.

I'm working through a coding challenge I found online. I have the first test case passing but failing the second. I'm trying to decide if the second test case I'm failing is a typo or not.

Here is the question:

You are given an array of desired filenames in the order of their creation. Since two files cannot have equal names, the one which es later will have an addition to its name in a form of (k), where k is the smallest positive integer such that the obtained name is not used yet.

Return an array of names that will be given to the files.

Test Cases:

1 - Passing:

  • INPUT: ["doc", "doc", "image", "doc(1)", "doc"]
  • OUTPUT: ["doc", "doc(1)", "image", "doc(1)(1)", "doc(2)"]

2 - Failing:

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

Here is my code that passes the first Spec:

function fileNaming(names) {
    var finalArr = [],
        obj = {};
    names.forEach(function(val){

        if(obj[val] === undefined){
            if(finalArr.indexOf(val) === -1){
              finalArr.push(val);  
              obj[val] = 0;
            } else {
              obj[val] = 1;
              finalArr.push(val + "(" + obj[val] + ")" );
            }

        } else {
            finalArr.push( val + "(" + (++obj[val]) + ")");
        }
    }); 
    return finalArr;
}

Question:

  • In the second test spec, why isn't there an "a(1)(1)" like there is a "doc(1)(1)" Is this a typo?
  • If anyone has suggestions on improvining my approach or alternative approaches I would greatly appreciate your feedback.
Share Improve this question asked Jan 24, 2016 at 3:46 HelloWorldHelloWorld 11.2k10 gold badges34 silver badges55 bronze badges 3
  • Shouldn't it be "a(2)" instead of "a(1)(1)"? – Matthew Herbst Commented Jan 24, 2016 at 3:53
  • I'm not sure, I think it should be. But if you look at the first example there is a "doc", "doc(1)", "doc(1)(1)", "doc(2)". – HelloWorld Commented Jan 24, 2016 at 3:55
  • The expected output looks correct. There shouldn't be a a(1)(1) because there doesn't exist a file named a(1) in the array prior to a(1) being encountered in the input. The requirement states the next minimum integer would be used if there exists a duplicate name. Since the next "a" iteration does not have a (1), it would be a(2). – Tah Commented Jan 24, 2016 at 3:56
Add a ment  | 

7 Answers 7

Reset to default 4

Here's a simpler approach. The idea is to store both the original and the generated name in the hashtable:

f = function(xs) {
  
  var c = {}, t = (x, n) => x + "(" + n + ")";
  
  return xs.map(function(x) {
    var n = c[x] || 0;
    
    c[x] = n + 1;

    if(!n)
      return x;
    
    while(c[t(x, n)])
      n++;
    
    c[t(x, n)] = 1;
    return t(x, n);
  });

};


q = ["doc", "doc", "image", "doc(1)", "doc", "doc"];
document.write('<pre>'+JSON.stringify(f(q)));

q = ["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"]
document.write('<pre>'+JSON.stringify(f(q)));

Here's my approach :

def fileNaming(names):
uniq = []
for i in range(len(names)):
    if names[i] not in uniq:
        uniq.append(names[i])
    else:
        k = 1
        while True:
            if (names[i] + "(" + str(k) + ")") in uniq:
                k += 1
            else:
                uniq.append(names[i] + "(" + str(k) + ")")
                break
return uniq

with arrray approch

//var arr=["doc", "doc", "image", "doc(1)", "doc"];
 var arr=["a(1)","a(6)","a","a","a","a","a","a","a","a","a","a"];  

 var arr1=new Array();  
    for (var r in arr)
    {
      if(arr1.indexOf(arr[r])>-1)
      {     
        var ind=1;
        while(arr1.indexOf(arr[r]+'('+ind+')')>-1)
        {
        ind++;      
        }
        var str=arr[r]+'('+ind+')';  
        arr1.push(str);
      }
      else
      {
      arr1.push(arr[r]);
      }
    }
    document.write("INPUT:"+arr+"</br>");
    document.write("OUTPUT:"+arr1);

This was my beginner approach:

const renameFiles = arr => {
  const fileObj = {};
  let count = 0;
  const renamed = arr.map(currentFile => {
    if (!Object.keys(fileObj).includes(currentFile)) {
      fileObj[currentFile] = count;
      return currentFile;
    } else {
      count++;
      if (Object.keys(fileObj).includes(`${currentFile}(${count})`)) {
        count++;
        return `${currentFile}(${count})`;
      } else return `${currentFile}(${count})`;
    }
  });
  return renamed;
};

Here is a working c++ impl.

#include <map>
#include <string> 
using namespace std;

string makeName(string n, int i)
{
    string ret = n + "(";
    ret += std::to_string(i);
    ret += ")";
    return ret;
}
std::vector<std::string> fileNaming(std::vector<std::string> names)
{
    map<string, int> lookup;
    vector<string> outNames;
    for (auto name : names)
    {
        auto f = lookup.find(name);
        if (f != lookup.end())
        {
            int index = 1;

            while (lookup.find(makeName(name, index)) != lookup.end())
            {
                index++;
            }
            name = makeName(name, index); // reassign
        }
        lookup[name] = 1;
        outNames.push_back(name);
    }

    return outNames;
}

JAVA version based on the accepted answer:

String[] solution(String[] names) {
    Map<String, Integer> countMap = new HashMap<>();
    String[] result = new String[names.length];
    for (int i = 0; i < names.length; i++) {
        int count = countMap.getOrDefault(names[i], 0);
        countMap.put(names[i], count + 1);
        if (count == 0) { 
            result[i] = names[i];
        } else {
            while (countMap.containsKey(names[i] + "(" + count + ")")) 
                count++;
            countMap.put(names[i] + "(" + count + ")", 1);
            result[i] = names[i] + "(" + count + ")";
        }
    }
    return result;
}

Here is my approach in Javascript:

function fileNaming(names) {
    for (i in names) {
        if (names.slice(0,i).includes(names[i])) {
            j = 1
            while (names.slice(0,i).includes(names[i]+"("+j.toString()+")")) {j++}
            names[i] += "(" + j.toString() + ")"}}
    return names
}
发布评论

评论列表(0)

  1. 暂无评论