1

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.

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
Richard B.
  • 13
  • 3

6 Answers6

1

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('-')
  }
}
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • That is brilliant, thank you so much for the clarity of your answer and the suggested improvement to my code. I can see now that including the .push in the for loop negagtes the need for the else statement. I can also see that by adding the .length -1 as a conditon to the if statement I ensure I am telling my if statement where to stop. – Richard B. Jun 15 '23 at 10:23
1

Just a regex-based solution

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

const str = "999463"

console.log(str.replace(/[13579](?=[13579])/g, '$&-'))
User863
  • 19,346
  • 2
  • 17
  • 41
0

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.

Serzhik
  • 11
  • 3
  • 1
    What did you change and why? – Felix Kling Jun 15 '23 at 10:03
  • I've changed `(str[i] % 2 !== 0 && str[i + 1] % 2 !== 0 )` to `(str[i] % 2 == 1 && str[i + 1] % 2 == 1 )`. Because at the end you have condition `(1 !== 0 && NaN !== 0 )` and it's true. – Serzhik Jun 15 '23 at 10:04
  • 1
    It would be good to edit your answer and include the explanation (in some extended form). I'm sure it's not obvious to many people. – Felix Kling Jun 15 '23 at 10:05
  • Thank you for this answer too. This helped me see why my if statement was passing the NaN value and adding the '-' to the end of my array. Thank you again to Felix as I wouldn't have grasped that without the additional clarifying comment. – Richard B. Jun 15 '23 at 10:26
0

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

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}`))
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
0

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(''));
Andy
  • 61,948
  • 13
  • 68
  • 95