-9

How could I implement a function in javascript which would take a list of strings as input, and would output the "smallest" (loosely speaking) type that all those strings can be parsed to?

Examples:

  • Input: ["true", "false", "false"] => Output: "boolean".

  • Input: ["1", "4", "-9"] => Output: "int".

  • Input: ["1", "4.3", "-9"] => Output: "float" (or "double", doesn't matter).

  • Input: ["9/1/2016", "2016-9-1"] => Output: "DateTime".

  • Input: ["1", "4.3", "9/1/2016", "Nastassja Kinski"] => Output: "string".

Remarks:

  • It's ok to label everything else (functions, objects, arrays) as "string".
  • It's ok to label anything date-related as "DateTime", even if there is not time component present.
  • It requires differentiation between int and float (that's why my ouputs are strings instead of native types such as Number).
  • It doesn't need to be perfect; just something that roughly works (at I can refine if needed).
  • The input arrays would have 100 elements each.

Thanks a lot!

ChrisF
  • 134,786
  • 31
  • 255
  • 325
zalofg
  • 1
  • 2
  • 1
    What is the goal here? Why do you need to know the type? – Adjit Sep 01 '16 at 19:32
  • 3
    SO is not a place where we write code for you. Ask specific questions and show us what you tried so far. – Tobias Sep 01 '16 at 19:34
  • 1
    ` Output: "DateTime".` Hoo, boy. Have fun with that. This can easily be an entire project by itself. – VLAZ Sep 01 '16 at 19:37
  • What makes one type "smaller" than another? Which is smaller, `int` or `DateTime`? – Barmar Sep 01 '16 at 19:38
  • And Javascript doesn't really have an `int` type. It represents all numbers using floating point. – Barmar Sep 01 '16 at 19:38
  • @Barmar: Google "partially ordered sets". – zalofg Sep 01 '16 at 20:43
  • @Vld: Doesn't look like it based on the answer I've accepted. – zalofg Sep 01 '16 at 20:44
  • @Adjit: Why do you need to know why I need to know? – zalofg Sep 01 '16 at 20:45
  • @zalofg That answer is browser-dependent, since different browsers recognize different date/time formats. – Barmar Sep 01 '16 at 20:45
  • 1
    @zalofg Google "XY problem" – Barmar Sep 01 '16 at 20:45
  • @Barmar: What's your point? It's a well-known problem. – zalofg Sep 01 '16 at 21:03
  • @zalofg Is it? I've never encountered it before. My point is that if we knew what this was being used for, we might be able to suggest a better overall method. – Barmar Sep 01 '16 at 21:04
  • @still_learning: No, you're not trying to help. Want to really help? Follow the example set below in the accepted answer. If you don't know the answer to a question, just move on. If you do know the answer but don't like the question, just down-vote it and move on. If something is unclear, please ask, otherwise move on. See a pattern here? The question is perfectly clear, and I'm not going have you tell me what I can or can't ask. – zalofg Sep 01 '16 at 21:34
  • @Barmar: The question is perfectly clear and has been answered, right? – zalofg Sep 01 '16 at 21:37

1 Answers1

1

Thinking about it declaratively, it's quite easy, if you think about the criteria:

function getType(arr) {
    if (arr.every(s => s === 'true' || s === 'false'))
        return 'boolean'
    else if (arr.every(s => isNaN(Number(s)) === false)) {
        if (arr.every(n => Number(n) % 1 === 0)) return 'int'
        else return 'float'
    }
    else if (arr.every(s => isNaN(Date.parse(s)) === false)) 
        return 'DateTime'
    else return 'string'
}

Testing with your inputs:

> getType(["true", "false", "false"])
'boolean'
> getType(["1","4","-9"])
'int'
> getType(["1","4.3","-9"])
'float'
> getType(["9/1/2016", "2016-9-1"])
'DateTime'
> getType(["1", "4.3", "9/1/2016", "Nastassja Kinski"])
'string'

The difficulty arises when people try to think of the code that produces the result; instead, if you think about what you want and not how to write the code, the requirements become more clear and the solution becomes more apparent.

The other thing to learn here is how we let javascript (or the language of choice if it's different) do as much work for us as possible. Use clear predicate syntax and built-in functions (isNaN and built-in Date objects), and it's only 8 lines of code and clear to understand.

Someone commented about the date format varying across implementations and this is a good point. Though common date formats are going to be supported on all major implementations, if we find that our date formats are more exotic, then we can simply write our own date validator and plug it in. Either way, the approach remains the same:

...
else if (arr.every(s => myCustomDateValidator(s)))
    return 'DateTime'
...
Josh
  • 4,726
  • 2
  • 20
  • 32
  • 1
    Awesome, I love it, I'm very new to javascript so I didn't even know javascript had something roughly similar to .NET's Linq queries (which I love). Thanks a lot! – zalofg Sep 01 '16 at 20:37
  • Thanks for the extra work on the date validator; great answer overall and exactly what I was looking for. – zalofg Sep 01 '16 at 21:46