Увеличение определенных чисел, содержащихся в строке

#javascript #string #increment

#javascript #строка #приращение

Вопрос:

Я работаю со строками, которые выглядят следующим образом:

 "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4"
 

Я хотел бы увеличить каждое число в строке за определенную точку, исключая числа рядом с ‘/’ или ‘x’. Например, если я хочу увеличить все числа вышеупомянутой строки после точки do3mi3so3, я бы ожидал получить это:

 "do3mi3so3 la4 ti5 do6 re6 mi6 /2 x2 fa5"
 

Вот мой код:

 function is_numeric(str){
    return /^d $/.test(str);
}


function change_octave(notes,split_point){
  for(var i=(split_point-1);i<notes.length;i  ){
    if(is_numeric(notes[i])==true){
      notes[i]=''   parseInt(notes[i]) 1;
      //console.log(parseInt(notes[i]) 1) //these numbers are incrementing
    }
    if(notes[i]=='/'||notes[i]=='x'){
      i = i 3;
    }
  }
  return notes;
}
var notes = "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4";
console.log(change_octave(notes,4)); 

Несмотря на успешное увеличение чисел, значение строки не изменяется.

Спасибо.

Комментарии:

1. Из любопытства, что приводит вас к выводу, что числа успешно увеличиваются, если значение строки не изменяется?

2. Я только что добавил закомментированную строку в свой приведенный выше код, демонстрирующую, из какой строки я почерпнул это понимание

Ответ №1:

На самом деле вы не можете установить символ строки по определенному индексу, используя что-то вроде notes[i] = "a" . Что вы можете сделать, это разбить строку на массив, изменить значения в этом массиве, а затем снова объединить их в строку, когда закончите.

 function is_numeric(str){
    return /^d $/.test(str);
}

function change_octave(notesStr,split_point){
  const notes = notesStr.split('');
  for(var i=(split_point-1);i<notes.length;i  ){
    if(is_numeric(notes[i])==true){
      const newValue = parseInt(notes[i])   1;
      notes[i] = ''   newValue;
    }
    if(notes[i]=='/'||notes[i]=='x'){
      i = i 3;
    }
  }
  return notes.join('');
}
var notes = "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4";
console.log(change_octave(notes,4)); 

Ответ №2:

В JavaScript строка является примитивным типом и поэтому неизменяема. По умолчанию, в так называемом «небрежном режиме», присвоение значения элементу строки автоматически завершается ошибкой, но в строгом режиме это приведет к ошибке:

 "use strict";
let notes = "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4";
notes[4] = "o"; 

Для достижения этой цели я бы предложил использовать String.prototype.replace() следующее:

 function change_octave(notes, split_point) {
  return notes.replace(/d /g, (str, i) => {
    if (--split_point > 0) {
      return str;
    }

    if (i > 0 amp;amp; (notes[i - 1] === '/' || notes[i - 1] === 'x')) {
      return str;
    }

    return Number(str)   1;
  });
}

let notes = "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4";

console.log(change_octave(notes, 4)); 

Ответ №3:

Я немного изменил ваш код, и я думаю, что теперь он работает!

  function is_numeric(str) {
        return /^d $/.test(str);
    }

    function change(note, point) {
        var arr = note.split("")
        var ind = note.indexOf(point)
        ind = ind   point.length -1;
        for (var i = 0; i < arr.length; i  ) {
            if (i > ind amp;amp; is_numeric(arr[i])) {
                if (arr[i - 1] !== undefined amp;amp; arr[i - 1] !== "/" amp;amp; arr[i - 1] !== "x") {
                    arr[i] = ""   (parseInt(arr[i])   1);
                }
            }
        }
        return arr.join("")
    }
    var notes = "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4";
    console.log(change(notes, "do3mi3so3"))
 

Вывод:

 do3mi3so3 la4 ti5 do6 re6 mi6 /2 x2 fa5
 

Если вы хотите использовать позицию индекса в качестве точки, то

 function change(note, point) {
        var arr = note.split("")
        var ind = point
        for (var i = 0; i < arr.length; i  ) {
            if (i > ind amp;amp; is_numeric(arr[i])) {
                if (arr[i - 1] !== undefined amp;amp; arr[i - 1] !== "/" amp;amp; arr[i - 1] !== "x") {
                    arr[i] = ""   (parseInt(arr[i])   1);
                }
            }
        }
        return arr.join("")
    }
 

Ответ №4:

Если вы хотите увеличить определенную часть строки примера, вы можете использовать шаблон для перечисления точных совпадений b([ds]o|re|mi|fa|la|ti)b и использовать границы слов для предотвращения частичных совпадений.

При обратном вызове replace вы можете увеличить совпадение групп для цифр.

 let regex = /b([ds]o|re|mi|fa|la|ti)(d )b/g;
const change_octave = notes => notes.replace(regex, (_, g1, g2) => g1     g2);

console.log(change_octave("do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4")); 

Для указания точки как количества символов, которое должно быть после начала строки, вы можете использовать lookbehind, для которого поддерживается этот браузер, и динамический шаблон для установки point

 const change_octave = (notes, point) => {
  let regex = new RegExp(`(?<=^.{${point}}.*\b(?:[ds]o|re|mi|fa|la|ti))\d \b`, "g");
  return notes.replace(regex, m =>   m);
}

console.log(change_octave("do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4", 4));
console.log(change_octave("la3 ti4 do5 re5 mi5 /2 x2 fa4", 4)); 

Ответ №5:

Вы не можете изменить символ в строке по индексу напрямую. Например:

    notes="aaa"
   notes[1] = "b"
   console.log(notes)
 

Решение таково:

 function is_numeric(str){
    return /^d $/.test(str);
}


function change_octave(notes,split_point){
  modified_notes = notes.split('')
  for(var i=(split_point-1);i<notes.length;i  ){
    if(is_numeric(notes[i])==true){
      modified_notes[i]='' (parseInt(notes[i]) 1);
      //console.log(parseInt(notes[i]) 1) //these numbers are incrementing
    }
    if(notes[i]=='/'||notes[i]=='x'){
      i = i 3;
    }
  }
  
  return  modified_notes.join('')  
}
var notes = "do3mi3so3 la3 ti4 do5 re5 mi5 /2 x2 fa4";
console.log(change_octave(notes,4));