Separating odd numbers in a string with '-'

70 Views Asked by At

I am attempting to take a string of numbers and iterate through that number. When there are two odd numbers adjacent to one another, I want to separate them with '-'.

For example, 999463 would become 9-9-9463.

const str = "999463"

const numberWithDash = []

for (let i = 0; i < str.length; i++) {
  if (str[i] % 2 !== 0 && str[i + 1] % 2 !== 0) {
    numberWithDash.push(str[i] + '-')
  } else {
    numberWithDash.push(str[i])
  }
};

console.log(numberWithDash.join(''))

This returns "9-9-9463-". Why is this adding an additional dash on the end of my code? I think this is because the final number in the string is odd, thereby it is being passed through the if statement, instead of the else stament.

If I amend 'i < str.length -1' then I just cut off the last number entirely, so that isn't right either. I think I need to make my if statement stricter by adding another condition to check if str[i] is a number, but not sure where to start.

6

There are 6 best solutions below

1
Felix Kling On BEST ANSWER

You can just check whether you are at the end of the string. That makes sense anyway since you don't want to test the next character in that case (there is none):

if (str[i] % 2 !== 0 && i < str.length - 1 && str[i + 1] % 2 !== 0 ) {

I'd probably turn some things around to make it slightly easier to read: We always need to append the current digit. We sometimes want to append a dash.

for (let i = 0; i < str.length; i++) {
  numberWithDash.push(str[i])

  if (str[i] % 2 !== 0 && str[i + 1] % 2 !== 0 && i < str.length - 1) {
    numberWithDash.push('-')
  }
}
4
Serzhik On

Try this

const str = "999463"

const numberWithDash = []

for (let i = 0; i < str.length; i++) {
  if (str[i] % 2 == 1 && str[i + 1] % 2 == 1 ) {
    numberWithDash.push(str[i] + '-')
  } else {
       numberWithDash.push(str[i])
    }
};

console.log(numberWithDash.join(''))

When you checking the last element in your string the result of srt[i + 1] % 2 is NaN. NaN !== 0 is true. I think better to compair with 1.

0
Matěj Kasper On

Change your cycle to for (let i = 0; i < str.length - 1; i++) {... as you did before, and after this for cycle add numberWithDash.push(str[str.length - 1]). I am sure it is correct coding of your problem. You musn't check last character in your cycle.

0
Andrew Parks On

You can treat the number as an array of numbers, and then use reduce. It checks whether both the prior number and the current number are odd in order to decide to include a dash.

Note that since n % 2 will either be 0 or 1, you don't need to write it as n % 2 === 1 to check if it's odd, because the number 1 is treated as true.

console.log([...'999463'].reduce((a,c,i,r) => 
  `${a}${r?.[i-1]%2 && c%2 ? '-' : ''}${c}`))

0
Andy On

You could add an additional condition && i < str.length - 1 to ensure that a dash isn't added if you're processing the last number.

But rather than pushing dashes into an array it might be simpler to create an array from the string, and then iterate from the end to the beginning, splicing in dashes where required.

const str = '999463';
const arr = [...str];

const isOdd = n => n % 2 !== 0;

for (let i = arr.length - 1; i > 0; i--) {
  if (isOdd(arr[i]) && isOdd(arr[i - 1])) {
    arr.splice(i, 0, '-');
  }
}

console.log(arr.join(''));

0
User863 On

Just a regex-based solution

Regex Demo: https://regex101.com/r/z068Qf/1

const str = "999463"

console.log(str.replace(/[13579](?=[13579])/g, '$&-'))