Top N clients in an access log
Coding, Easy
Small real code that works when called late, twice, or with bad input.
Write topIps(lines, n) in JavaScript (or the same idea in another language, or a shell pipeline). lines is a list of access-log lines. Each line starts with the client address, then a space, then the rest of the line (for example 10.0.0.5 GET /home 200). Return the n addresses that appear most often, as a list of objects { ip, count }, with the most frequent first. If two addresses have the same count, the one that is smaller as text comes first. If there are fewer than n addresses, return all of them. Skip lines that are empty or contain only spaces.
Examples
Input lines = ["10.0.0.5 GET /a 200", "10.0.0.9 GET /b 200", "10.0.0.5 GET /c 404", "10.0.0.7 POST /a 500", "10.0.0.5 GET /a 200", "10.0.0.9 GET /a 200"], n = 2
Output [{ip:"10.0.0.5",count:3},{ip:"10.0.0.9",count:2}]
Why 10.0.0.5 has 3 lines and 10.0.0.9 has 2. 10.0.0.7 has 1.
Input lines = ["b 1", "a 1", "c 1", "a 1", "b 1"], n = 3
Output [{ip:"a",count:2},{ip:"b",count:2},{ip:"c",count:1}]
Why a and b are tied at 2, so the smaller text "a" comes first.
Input lines = ["", " "], n = 5
Output []
Why Edge case: blank lines are skipped, so nothing is counted.
Constraints
- 0 <= number of lines <= 1,000,000. Each line is at most 1,000 characters.
- 0 <= n. If n is 0, return an empty list.
- Compare addresses as plain text. Do not parse them as numbers.
- Do not read a line twice, and do not keep the lines in a second copy.
Your answer must contain
- The code (or the shell pipeline)
- How you get the address from a line and what you do with a blank line
- The order rule and how you apply it, including ties
- Time and memory cost, in one or two sentences