1

If the string contains any characters besides a number or the comma that separates it from the other character the function should return "invalid input", if they're all numbers it should output "great job"

a,4,3,@ = "invalid input"...

1,4,6,5 = "great job" <===returned from function

I'm trying to learn about regex but if you could do it using another method that's ok. I'm interested in how you would go about solving it. I couldn't find an answer online my self. I searched. I know that d(regex) is for digits but I just don't now how to apply it for this case.

Rahul Nori
  • 698
  • 6
  • 17
jack blank
  • 5,073
  • 7
  • 41
  • 73

7 Answers7

2

You can use a simple regular expression to check that the string contains only comma separated numbers:

/^(\d+,)*\d+$/.test(s)

And use it like:

['1,2,3','123,5,223','1@32','12','12,',',23',','].forEach(function(s) {
  document.write('<br>' + s + ' : ' + (/^(\d+,)*\d+$/.test(s)? 'great job' : 'invalid input'));
});

This assumes that numbers can have any number of digits and that commas are only allowed between numbers; not at the start, end or consecutively.

RobG
  • 142,382
  • 31
  • 172
  • 209
1

You can split a string into an array on a character using String.split(char), for example:

'1,4,6,5'.split(',');
> [1, 4, 6, 5]

You could then use a regex to check if the character is a number and a reducer to validate.

function valid(c) {
   //using regex, return true if the character is valid, false if not
   // or something like
   return !Number.isNaN(+c);
}

'1,4,6,5'.split(',').reduce(function(acc, x) {
     if valid(x) {
        return acc;
     } else {
        return false;
     }
 }, true);

that should give you a boolean that you can map to your desired output string. reduce works sort of like a loop, it passes an accumulated value and each element of the array one at a time, with the inital value given as at the part here '}, true);' so as long as the regex returns true, we keep returning the same acc value, but if we get an invalid regex we switch the accumulator to false. note that because we don't change the accumulator value on valid inputs, we don't have to worry about it suddenly reventing back to a 'valid' status.

Jonah Williams
  • 20,499
  • 6
  • 65
  • 53
  • Only thing I'd do here is not bother running `valid` after a previously invalid result. Micro optimisation and all that :) – Phil Oct 08 '15 at 03:33
  • 1
    something, something root of all evil ;) – Jonah Williams Oct 08 '15 at 03:34
  • *some* or *every* would be a better solution as they will quit as soon as an invalid result is detected rather than continue to the end regardless. A regular expression is about 5 times faster. – RobG Oct 09 '15 at 05:48
1

You can use the Array.prototype.every() method

return str.split(',').every(function(val) {
    return parseInt(val) == val; // or any of the many other ways to check if a string is a number
});
Phil
  • 157,677
  • 23
  • 242
  • 245
  • 1
    messed with your regex (before edit) this `/^\d*(,\d+)*$/` this would work with single numbers and return true for empty strings –  Oct 08 '15 at 03:18
  • Yeah, I decided to change from a regex solution – Phil Oct 08 '15 at 03:19
  • soo it's up for grabs? :) –  Oct 08 '15 at 03:19
  • Sure, but it's pretty similar to RobG's – Phil Oct 08 '15 at 03:20
  • 1
    I liked your regexp answer... just saying.. I'm not saying I'm going to chose your answer, just that I liked your explanation with the regex maybe you could still have it up there so other could see. – jack blank Oct 08 '15 at 03:22
  • 1
    If speed matters, iterators like *every* are [*slow*](http://jsperf.com/every-with-split-vs-loop-with-regexp). – RobG Oct 08 '15 at 04:56
1

Helpful links:

Check whether an input string contains number

Check if string contains only digits

I threw this together, hopefully it helps! It is a working function, like you asked.

function isOnlyNumsAndCommas(str) {
  for (var i = 2; i <= str.length + 2; i += 2) {
    var val = str.substring(i - 2, i - 1);
    var isnum = val.match(/\d+/g);
    if (!isnum) {
      return ('invalid input');
      break;
    }
  }
  return('great job');
}

alert(isOnlyNumsAndCommas("@,4,3,3"));

For a non 'for loop' function!

function isOnlyNumsAndCommas(str) {
  if (str.match(/[^\d|,]/) === null) {
    return('great job');
  } else {
    return('invalid input');
  }
}

alert(isOnlyNumsAndCommas("a,4,3,@"));
Community
  • 1
  • 1
johnchinjew
  • 150
  • 1
  • 1
  • 6
  • The "non for loop" version returns true for values like ',,,' and ',2,' when it probably should not. – RobG Oct 08 '15 at 05:04
0

var hasCommaSeparatedDigits = function(str){
    var strArr = str.split(",");
    var res = strArr.length ? "Great job!" : "Invalid Input";
    for(var i in strArr){
     var ch = strArr[i];
        if(isNaN(ch)){
            res = "Invalid Input";
            break;
        }
    }
    
    return res;
}

console.log(hasCommaSeparatedDigits("1,2,3,4"));
console.log(hasCommaSeparatedDigits("1,a,3,4"));
Bhargav Ponnapalli
  • 9,224
  • 7
  • 36
  • 45
0

There is no need to split the string, loop and check for validity of each part. Just do a regex check for presence of a non-digit excluding the comma (this assumes that a comma can occur anywhere)

try:

var str = "1,2,3,";
if(str.match(/[^\d|,]/) == null)
 alert("great job");
else
 alert("err");
TarunG
  • 602
  • 5
  • 21
0
function isValid(str){
    var res = str.split(',').every(function(item){ 
        return !isNaN(item) ? true : false;
  });
return res ? "great job" : "invalid input";
}
console.log(isValid("1,2,4,5,@"))
  • 1
    *isNaN* returns true or false, so `!isNaN(item) ? true : false` should be just `!isNaN(item)` – RobG Oct 08 '15 at 05:06