Можете ли вы помочь мне упростить код JavaScript в нескольких строках?

#javascript

#javascript

Вопрос:

У меня есть код JavaScript, который получает текст песни, которая в данный момент воспроизводится через API.

Иногда (не всегда) текст возвращает заголовок в начале, который я хочу удалить.

Иногда заголовок в начале написан в верхнем регистре, в других случаях в верхнем и нижнем регистре.

Пример:

 SWEET CHILD O' MINE

She's got a smile that it seems to me

Reminds me of childhood memories

Where everything was as fresh as the bright blue sky

Now and then when I see her face

She takes me away to that special place

And if I stare too long, I'd probably break down and cry
........
  

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

Я хочу посмотреть, помогут ли они мне упростить этот код в меньшем количестве строк.

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

currentSong содержит название воспроизводимой песни

lyric содержит полный текст, полученный с помощью API

 this.refreshLyric = function(currentSong, currentArtist) {
    
    //another code that does not interest
    //...
    //...
    
    //lyric variable contains the complete lyrics of a song obtained through an API
    var lyric = data.mus[0].text;

    
    //divide the string CurrentSong (contains the song title) into parts
    let splitCurrenSong = currentSong.split(' ');
    
    //I get the length of the array
    let largeCurrentSong = splitCurrenSong.length;
    
    //divide the string lyric into parts                            
    let splitLyric = lyric.split(' ');
                    
    //I get the first elements of the lyric array with the length limit of largeCurrentSong
    let pieceLyric = splitLyric.slice(0, largeCurrentSong);
    
    //I get all elements of the splitCurrenSong array
    let pieceSong = splitCurrenSong.slice(0, largeCurrentSong);
    
    //join arrays 
    let joinLyric = pieceLyric.join(' ');
    let joinSong = pieceSong.join(' ');
        
        //I check if the chunk of the joinLyric string matches the same chunk of joinSong
        if (joinLyric.toLocaleLowerCase() == joinSong.toLocaleLowerCase()) {
            //remove the matching items
            splitLyric.splice(0, largeCurrentSong);
            //put the resulting join array into a variable
            lyrics = splitLyric.join(' ');
            //remove the spaces from the beginning and end of lyrics
            lyric = lyrics.trim()
        }   
    
    //another code that does not interest
    //...
    //...

}
  

РЕДАКТИРОВАТЬ: для ответа на @iamaword

Возврат API

Как показано на скриншоте возврата API:

text: содержит текст полной песни

name: название песни

Я могу прекрасно получить название песни с помощью этой строки: var nameSong = data.mus[0].name

Но я не думаю, что это необходимо, поскольку я получаю название песни из currentSong переменной, которая отправляется в GET команде для получения текста.

ОКОНЧАТЕЛЬНАЯ ПРАВКА: спасибо @CerebralFart

полный код:

 this.refreshLyric = function(currentSong, currentArtist) {
        
      var proxy_URL = PROXYURL;
      var vagalume_api = 'https://api.vagalume.com.br/search.php?';
      
      var xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState === 4) {
          if (this.status === 200) {
             var data = JSON.parse(this.responseText);

                    if (data.type === 'exact' || data.type === 'aprox') {
                        var lyric = normalizeText(data);

                                                                        
                        document.getElementById('lyric').innerHTML = lyric.replace(/n/g, '<br />');
                        var openLyric = document.getElementsByClassName('lyrics')[0];
                        openLyric.style.opacity = "1";
                        openLyric.setAttribute('data-toggle', 'modal');
                        var powered = "Vagalume"
                        var URL_lyric = 'https://www.vagalume.com.br';
                        
                        //Powered by image src...
                        const parent = document.querySelector('.chartlyrics');
                        parent.innerHTML = '';
                        var img = document.createElement("img");
                        img.src = "img/103-fundo-escuro.jpg"
                        img.setAttribute('class', "")
                        parent.appendChild(img);
                        parent.appendChild(document.createElement('br'));
                        parent.append('Powered by ');
                        
                        // Powered by link a href...                        
                        document.getElementById('powered_by').innerHTML = ''
                        var a = document.getElementById('powered_by')
                          .appendChild(document.createElement("a"));
                          
                        a.href = URL_lyric;
                        a.target = "_blank";
                        a.rel = "noopener noreferrer";
                        a.textContent = powered;
                    } else {
                        var page = new Page();
                        page.refreshLyric2(currentSong, currentArtist);
                    }
                } else {
                   var page = new Page();
                    page.refreshLyric2(currentSong, currentArtist);
                   }
            }
        }
            xhttp.open('GET', proxy_URL   vagalume_api   API_KEY   'amp;art='   currentArtist   'amp;mus='   currentSong.toLowerCase(), true);
            xhttp.send()
    }

function normalizeText(response){
  // First unpack the data, get the right name and text values
  let {mus:[{name, text}]} = response;

  // Now get the part of the text that might be the title
  let titleLength = name.length;
  let maybeTitle = text.substring(0, titleLength);

  // Compare the two titles and trim if they match
  if (name.toLowerCase() === maybeTitle.toLowerCase() amp;amp; exceptions.includes(maybeTitle.toLowerCase()) == false){
    text = text.substring(titleLength)
  }
  
  //Remove any leading or trailing whitespace and return
  return text.trim();
}

//song names excepted from being removed in lowercase ['one song', 'two song', etc..]
const exceptions = ['sweet emotion'];
  

Я создал список названий песен, которые не были удалены, на случай, если в каком-либо из них название песни упоминается как часть текста.

Это относится, например, к хорошо известной песне Aerosmith — Sweet Emotion.

 Sweet emotion
Sweet emotion

You talk about things and nobody cares
You're wearing other things that nobody wears
You're calling my name but you gotta make clear
I can't say baby where I'll be in a year
.....
  

Я добавил новое условие в normalizeText функцию, чтобы проверить, не входит ли название удаляемой песни в исключения.

 // Compare the two titles and trim if they match
      if (name.toLowerCase() === maybeTitle.toLowerCase() amp;amp; exceptions.includes(maybeTitle.toLowerCase()) == false){
  

И я создал константу exceptions , где названия песен в нижнем регистре должны добавляться вручную через запятую.

 //song names excepted from being removed in lowercase ['one song', 'two song', etc..]
    const exceptions = ['sweet emotion'];
  

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

1. вводятся ли тексты с символами новой строки, которые вы могли бы разделить с помощью регулярного выражения, такого как lyrics.split(/ r? n /)

2. Да, текст песни поставляется с n

3. также * можете ли вы получить название через тот же API, из которого вы получаете текст песни? потому что, если вы можете, вы могли бы просто выполнить некоторые проверки первого фрагмента текста, чтобы увидеть, соответствуют ли они названию

4. Да, заголовок также может быть получен через тот же API.

5. Я бы разделил на новую строку, а затем знал, что первым массивом будет заголовок (или нет). Это, по крайней мере, сужает поиск до способа определения, является ли конкретная строка заголовком или нет.

Ответ №1:

Есть несколько способов, которыми ваш код может быть очищен, в основном, тем, как вы распаковываете данные и как вы сравниваете две строки.

 function normalizeText(response){
  // First unpack the data, get the right name and text values
  let {mus:[{name, text}]} = response;

  // Now get the part of the text that might be the title
  let titleLength = name.length;
  let maybeTitle = text.substring(0, titleLength);

  // Compare the two titles and trim if they match
  if (name.toLowerCase() === maybeTitle.toLowerCase()){
    text = text.substring(titleLength)
  }
  
  //Remove any leading or trailing whitespace and return
  return text.trim();
}
  

РЕДАКТИРОВАТЬ: добавлена ошибка sintax в нижнем регистре ()

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

1. Я отредактировал, чтобы поделиться полным кодом, потому что я не знаю, как реализовать эту функцию в моем коде

2. Вызовите эту функцию с data в качестве аргумента вместо строк var lyric = data.mus[0].text; через END my proposed code : используйте const lyric = normalizeText(data);

3. Я исправил небольшую ошибку в .toLowerCase отсутствующих круглых скобках, теперь это работает.

4. Извините @CerebralFart, я осмелился отредактировать ваш ответ из-за этой опечатки, но мне нужно одобрение доверенного члена сообщества для завершения редактирования. Я очень благодарен за ваш правильный ответ. 🙂