4

var string = "3y4jd424jfm

Ideally, I'd want it to be ["3","y","4","j","d","4","24","j","f","m"]

but when I split: string.split(""), the 2 and the 4 in 24 are separated. How can I account for double digits?

Edit: Here is the question I was trying to solve from a coding practice:

Using the JavaScript language, have the function EvenPairs(str) take the str parameter being passed and determine if a pair of adjacent even numbers exists anywhere in the string. If a pair exists, return the string true, otherwise return false. For example: if str is "f178svg3k19k46" then there are two even numbers at the end of the string, "46" so your program should return the string true. Another example: if str is "7r5gg812" then the pair is "812" (8 and 12) so your program should return the string true.

Martina
  • 41
  • 3
  • 5
    What makes it `4, 24` instead of `42, 4`? – Ry- Aug 19 '18 at 07:03
  • @Ry- Yea, that's what I didn't get as well. I was doing a coding practice and that was a question. I will add the exact question above in an Edit. – Martina Aug 19 '18 at 07:25
  • Oh, that means it doesn’t matter which one of those it is. You can simplify the problem by considering each sequence of digits individually – `"3"`, `"4"`, and `"424"`, or `"178"`, `"3"`, `"19"`, and `"46"`. See if you can figure out what makes it possible to find a pair of even numbers in a single string of consecutive digits. – Ry- Aug 19 '18 at 07:33
  • @Ry- I split it into an array and had a `for` loop and in it, I checked if `arr[x] % 2 === 0 && arr[x + 1] % 2 ===0`, to return true, but that approach only takes into account each integer individually – Martina Aug 19 '18 at 07:42
  • @Martina did none of the answers fulfills your requirement/ solved your problem? Or you looking for something else? – Koushik Chatterjee Sep 04 '18 at 12:16

4 Answers4

2

You could take a staged approach by

  • getting only numbers of the string in an array
  • filer by length of the string,
  • check if two of the digits are even

function even(n) {
    return !(n % 2);
}

function checkEvenPair(string) {
    return string
        .match(/\d+/g)
        .filter(s => s.length > 1)
        .some(s => 
            [...s].some((c => v => even(v) && !--c)(2))
        );
}

console.log(checkEvenPair('2f35fq1p97y931'));   // false
console.log(checkEvenPair('3y4jd424jfm'));      // true  4  2
console.log(checkEvenPair('f178svg3k19k46'));   // true  4  6
console.log(checkEvenPair('7r5gg812'));         // true  8 12
console.log(checkEvenPair('2f35fq1p97y92321')); // true  (9)2 32

A regular expression solution by taking only even numbers for matching.

function checkEvenPair(string) {
    return /[02468]\d*[02468]/.test(string);
}

console.log(checkEvenPair('2f35fq1p97y931'));   // false
console.log(checkEvenPair('3y4jd424jfm'));      // true
console.log(checkEvenPair('f178svg3k19k46'));   // true
console.log(checkEvenPair('7r5gg812'));         // true
console.log(checkEvenPair('2f35fq1p97y92321')); // true
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • wouldn't stripping the alphanumeric characters change things though? " *the str parameter being passed and determine if a pair of adjacent even numbers exists anywhere in the string* " It's looking for adjacent even numbers within the string so stripping the letters might falsely put integers next to each other, right? – Martina Aug 19 '18 at 07:51
  • you get an array with adjacent digits, like for the first string this: `[ "2", "35", "1", "97", "931"]` and then all items are treates separately. then you just need to check a digit for evenness plus always the the last one, because the last digit decides for a number. – Nina Scholz Aug 19 '18 at 07:53
  • @NinaScholz if the string is *2f35fq1p97y92321* then it should return *true* as *2* and *32* or *92* and *32* are adjacent. – Koushik Chatterjee Aug 19 '18 at 16:08
  • hmm, now it looks correct, I feel a simple RegExp could have been better to check for 2 subsequent even digits (or separated by any digit(s)). Anyway you are using RegExp for splitting and further actions. – Koushik Chatterjee Aug 19 '18 at 16:24
1

Use regex for number extract then split for char as following:

var regex = /\d+/g;
var string = "3y4jd424jfm";
var numbers = string.match(regex); 

var chars = string.replace(/\d+/g, "").split("");

var parts = numbers.concat(chars);

console.log(parts);
Mohammad Akbari
  • 4,486
  • 6
  • 43
  • 74
0

Starting from this example 7r5gg812, the answer is true because there's a couple of even numbers 8 and 12 next to each other.

A possible solution is to iterate over the string with a counter that is incremented when you see an even digit, reset to 0 when it's not a digit. Odd digits are simply ignored:

function EvenPairs(str) { 
  let counter = 0;
  for (let i = 0; i < str.length; i++) {
    if (isNaN(str[i] % 2)) {
      counter = 0;
    } else if (str[i] % 2 === 0) {
      counter++;
    }

    if (counter === 2) {
        return true;
    } 
  }
  return false; 
}

Other solution, using regexps:

function EvenPairs(str) { 
    return /\d\d/.test(str.replace(/[13579]/g, ''));
}
Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75
0

You can use RegExp for that, you don't need to check if two numbers are even, you just need to check two constitutive chars (which is numbers) are even. so for 1234 you don't have to check 12 and 34 in that case the question could have been more complicated (what will be solved here). you just need to check [1 & 2], [2 & 3], [3 & 4] where none of them are even pairs.

And we can avoid parsing string and read as number, arithmetic calculation for even,.. and such things.

So, for the the simple one (consicutive even chars)

Regex for even digit is : /[02468]/

<your string>.match(/[02468]{2}/) would give you the result.

Example:

function EvenPairs(str) {
  let evensDigit = '[02468]',
      consecutiveEvenRegex = new RegExp(evensDigit + "{2}");
  return !!str.match(consecutiveEvenRegex);
}

let str1 = "f178svg3k19k46"; //should be true as 4 then 6
let str2 = "7r5gg812"; // should be false, as 8 -> 1 -> 2 (and not 8 then 12)

console.log(`Test EvenPairs for ${str1}: `, EvenPairs(str1));
console.log(`Test EvenPairs for ${str2}: `, EvenPairs(str2));

Now back to the actual (probable) problem to check for 2 constitutive even numbers (not only chars) we just need to check the existence of:

<any even char><empty or 0-9 char><any even char> i.e. /[02468][0-9]{0,}[02468]/

let's create a working example for it

function EvenPairs(str) {
  let evenDigit = '[02468]',
      digitsOrEmpty = '[0-9]{0,}',
      consecutiveEvenRegex = new RegExp(evenDigit + digitsOrEmpty + evenDigit);
  return !!str.match(consecutiveEvenRegex);
}

let str1 = "f178svg3k19k46"; //should be true as 4 then 6
let str2 = "7r5gg812"; // should be true as well, as 8 -> 12

console.log(`Test EvenPairs for ${str1}: `, EvenPairs(str1));
console.log(`Test EvenPairs for ${str2}: `, EvenPairs(str2));
Koushik Chatterjee
  • 4,106
  • 3
  • 18
  • 32
  • btw, why pipes in a character class? pipe would be a valid character. – Nina Scholz Aug 19 '18 at 16:47
  • just to match with any of them as `pipe` determines or inside *[]* – Koushik Chatterjee Aug 19 '18 at 16:49
  • to use *pipe* as a character you have to escape it like **\|** – Koushik Chatterjee Aug 19 '18 at 16:53
  • hm. not really. pipe is a legal character. it does not need to be escaped in a *character class* `[...]`, but if you take it as *or* separator in *group* `(...)`. – Nina Scholz Aug 19 '18 at 16:55
  • Exactly. so in this context (as I am using as a or operator inside char classes *[...]*) you need to escape it if you need a char as a pipe inside it. Yes, in general you are right (my reply wasn't in general context, if it sounds like that, that's my bad) outside char class also you can use pipe as a or. – Koushik Chatterjee Aug 19 '18 at 16:58
  • the regex for even digits is `[02468]`, not `[0|2|4|6|8]`. the later look for pipe as well, even one would be suficient (and wrong). – Nina Scholz Aug 19 '18 at 17:02
  • @NinaScholz, edited. actually right `[02468]` is enough, technically `[0|2|4|6|8]` may be correct but the or operator is not required as the `[]` meant any on them (char) – Koushik Chatterjee Aug 19 '18 at 17:07
  • please check `console.log(/[0|2|4|6|8]/.test('|'));`. – Nina Scholz Aug 19 '18 at 17:14
  • hmm, so for the case `39|19|` or `32|19` it would be `true` as per `[0|2|4|6|8]`, **+1** for the catch. `|` just an or operator outside `[...]` char class, what I have used inside earlier. – Koushik Chatterjee Aug 19 '18 at 17:20