Reorder Data in Log Files - Javascript

I'm trying to solve the Reorder Data in Log Files algorithm.

You have an array of logs. Each log is a space delimited string of words.

For each log, the first word in each log is an alphanumeric identifier. Then, either:

Each word after the identifier will consist only of lowercase letters, or; Each word after the identifier will consist only of digits. We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier.

Reorder the logs so that all of the letter-logs come before any digit-log. The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. The digit-logs should be put in their original order.

Return the final order of the logs.

Example:

Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"] Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"] 

My idea is having a map for the digits and one for the letters. I have done it. Then, I would need to sort the digits and letters and add all the sorted letters to my answer array and all the sorted digits to my answer array.

var reorderLogFiles = function(logs) { if(!logs || logs.length === 0) return []; let numbers = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9 }; let digits = new Map(); let letters = new Map(); for(let i=0; i<logs.length; i++) { const log = logs[i].split(" "); if(numbers[log[1]] !== undefined) digits.set(log[0], log.splice(1, log.length)); else letters.set(log[0], log.splice(1, log.length)); } // How can I sort letter and digits? let ans = []; for(const [key, value] of sortedLetters) { const temp = key + " " + value.join(" "); ans.push(temp); } for(const [key, value] of sortedDigits) { const temp = key + " " + value.join(" "); ans.push(temp); } return ans; }; 

1 Answer

I think you can simplify your code somewhat. First, create the digits and letters groups by filtering the original logs; this can be made easier by first splitting all the values in logs. Next, sort the letters based on the second value in the array and add the digits to the end of the sorted array. Finally, join the strings back together:

const reorderLogFiles = logs => { // split values on first space logs = logs.map(v => v.split(/\s+(.*)/).filter(Boolean)); // filter into digits and letters let digits = logs.filter(v => v[1].match(/^[\s\d]+$/)); let letters = logs.filter(v => v[1].match(/^[a-z\s]+$/)); // sort the letters letters.sort((a, b) => (c = a[1].localeCompare(b[1])) ? c : a[0].localeCompare(b[0])); // reassemble the list result = letters.concat(digits); // and convert back to strings result = result.map(a => a.join(' ')); return result; } let logs = ["dig1 8 1 5 1", "let1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"]; console.log(reorderLogFiles(logs)); logs = ["a1 9 2 3 1", "g1 act car", "zo4 4 7", "ab1 off key dog", "a8 act zoo", "a2 act car"]; console.log(reorderLogFiles(logs));

Note this code can be written more compactly by chaining operations but I've written it out more fully to make it easier to follow.

If you don't want to use regex, you can test the first character of each substring to see if it's a digit or letter. For example:

let digits = logs.filter(v => v[1][0] >= '0' && v[1][0] <= '9'); let letters = logs.filter(v => v[1][0] >= 'a' && v[1][0] <= 'z'); 
6

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like