2

You are given an array of desired filenames in the order of their creation. Since two files cannot have equal names, the one which comes 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.

Example

For names = ["doc", "doc", "image", "doc(1)", "doc"], the output should be fileNaming(names) = ["doc", "doc(1)", "image", "doc(1)(1)", "doc(2)"].

One person posted this solution:

const fileNaming = names => {
    const used = {};
    return names.map(name => {
        let newName = name;
        while (used[newName]) {
            newName = `${name}(${used[name]++})`;
        }
        used[newName] = 1;
        return newName;
    });
};

I'm having a hard time understanding the while block's condition.

used is an empty object.

newName is a new variable that is equal to the current item in the names array.

How does used[newName] resolve to a number? used is never set to anything other then an empty object.

This is the console output for console.log(used[newName])

enter image description here

Using this input:

["dd", 
 "dd(1)", 
 "dd(2)", 
 "dd", 
 "dd(1)", 
 "dd(1)(2)", 
 "dd(1)(1)", 
 "dd", 
 "dd(1)"]
5
  • 2
    One person posted this solution is alarming. Did you come up with your own solution yet? Commented Jan 6, 2021 at 1:39
  • please output in your console.log() also the values for name and newName. I have a feeling that you might understand the loop after seeing what's there. Commented Jan 6, 2021 at 1:40
  • you say used is never set to anything other then an empty object.. But in the sample code, there's this line: used[newName] = 1; . It contradicts your statement. ;-) Perhaps that's the key for you to understand the loop? Commented Jan 6, 2021 at 1:42
  • I did not come up with my own solution. The platform showcased other users answers and this was the most voted for. Commented Jan 6, 2021 at 1:54
  • Hint: Search for "postfix increment operator". Commented Jan 6, 2021 at 3:11

1 Answer 1

1

In JavaScript, {} is an empty object - and as such, it can contain any number of key-value pairs. A key that is not defined has the value undefined, which evaluates to false when tested. However, any non-zero, non-NaN numerical value will evaluate to true:

console.log({}["a key that does not exist"])                 // undefined
while (undefined) {
    console.log("this should never be printed");             // never executes
}
while ({}["a key that does not exist"]) {
    console.log("this should never be printed");             // never executes
}
if (1) {
    console.log("positive numbers are true");                // writes to console
}

You can use objects as maps (even though you can also use actual maps instead in newer code)

A simpler version of the above program would have written

return names.map(name => {
    let newName = name;
    while (used[newName] !== undefined) {       // tests for "not undefined"
        newName = `${name}(${used[name]})`;     // uses current value
        used[name] = used[name] + 1;            // sets a larger value            
    }
    used[newName] = 1;                          // sets a value
    return newName;
});
Sign up to request clarification or add additional context in comments.

2 Comments

My follow up is probably going to be 'wrong?', but bear with me. used is an empty object. We aren't adding anything to it. Wouldn't use[newName ALWAYS be undefined? How is it ever returning a truthy value? However, I understand there is a concept I am not fully understanding so thanks for tolerating me haha
You can add or set key-value entries in a JS object via object["key"] = value, which is equivalent to object.key = value. However, the [] notation allows using a key which is a variable: let foo = "quix"; object.foo = "bar" is equivalent to object["foo"] = "bar", while let foo = "quix"; object[foo] = "bar" is equivalent to object["quix"] = "bar"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.