Como posso encontrar as palavras mais longas na string e retorná-las (excluindo duplicatas) junto com o comprimento máximo?


8

Eu sei como posso encontrar a palavra mais longa em uma string. Por exemplo, este código aqui. Mas aqui o problema é que a palavra "bbbbbb" é encontrada porque ele é a PRIMEIRA PALAVRA MAIS LONGA DA string, depois disso, com 6 caracteres, também temos a palavra "saltou". Minha pergunta é como posso encontrar neste caso e a palavra "saltou", então todos eles não são apenas o primeiro.

UPDATE: quero uma lista exclusiva, portanto, apenas uma de cada palavras

function longestWord(sentence) {
  sentence = sentence.split(' ');

  let theWord = sentence[0];
  var longest = 0;
  for (let i = 0; i < sentence.length; i++) {
    if (sentence[i] != "") {
      if (sentence[i].length > theWord.length) {
        longest = sentence[i].length;
        theWord = sentence[i];
      }
    }
  }
  return {
    length: longest,
    actuallWord: theWord
  }
}
console.log(longestWord("The quick brown as bbbbbb fox jumped over the bbbbbb lazy dog"));


Tente sentence.filter(w => w.length === longest)obter uma matriz de palavras com esse comprimento.
— Rafi

Você pode tentar criar uma matriz para conter as palavras mais longas adicionadas. Em seguida, você pode usar filter () ou map () para avaliar o comprimento e adicionar à matriz.
— CoderLee

Agora você tem duas respostas com palavras únicas: Yevhen's e FZs
— mplungjan

Respostas:


9

function longestWord(sentence) {
  // First we divide the sentence into words
  var words = sentence.split(' ');
  
  // We then get the length by getting the maximun value of the length of each word
  var length = Math.max(...words.map(a=>a.length));
  return {
    length: length,
    // Finally we filter our words array returning only those of with the same length we previously calculated
    words: words.filter(i => i.length == length)
  }
}
console.log(longestWord("The quick brown as bbbbbb fox jumped over the lazy dog"));


Bom para obter o comprimento em uma declaração. Preciso de mais porque .sort não retorna a matriz
— mplungjan

3
@LuisfelipeDejesusMunoz Por que não adicionar uma explicação? É bom para outros leitores que encontrarem essa resposta. Além do OP.
— CoderLee

@YevgenGorbunkov Sua solução também é ótima. Obrigado companheiro
— Trajce12

A solução acima não pula palavras duplicadas e o algoritmo que está sendo implementado não é o ideal, pois requer desnecessariamente 2 passagens pela matriz, enquanto a abordagem de passagem única pode obter um desempenho 15% melhor, mesmo para uma sequência de teste tão curta.
— Yevgen Gorbunkov

@YevgenGorbunkov Você está certo sobre desempenho, mas não tenho certeza se o OP queria obter palavras únicas (essa parte foi editada na pergunta por outras pessoas )
— FZs

2

Você pode adotar uma abordagem de loop único e verificar a extensão de cada palavra com o comprimento dos acumuladores do primeiro item.

function longestWords(words) {
    return words
        .split(/\s+/)
        .reduce((accu, word) => {
            if (!accu[0] || accu[0].length < word.length) return [word];
            if (accu[0].length === word.length) accu.push(word);
            return accu;
        }, []);
}

console.log(longestWords("The quick brown as bbbbbb fox jumped over the lazy dog"));


@mplungjan: Interessante como estilos diferentes atraem pessoas diferentes. Acho essa uma das respostas mais fáceis de ler. Claro que talvez seja porque é semelhante à resposta que escrevi ... mas não publiquei porque Nina me venceu.
— Scott Sauyet

2

Você pode fazer isso com Array.prototype.reduce()uma única passagem pela matriz (sem loop extra para calcular o comprimento máximo).

A idéia é redefinir a matriz resultante com uma única palavra, uma vez que seu comprimento exceda os que foram inseridos antes ou acrescentados se a palavra atual tiver o mesmo tamanho ou simplesmente passar de outra forma:

const src = 'The quick brown as bbbbbb fox jumped over the jumped lazy dog',

      result = src.split(' ')
                  .reduce((res, word, idx) => {
                    if(!idx || word.length > res.length)
                        res = {length: word.length, words:new Set([word])}
                    else if(word.length == res.length)
                        res.words.add(word)
                    return res
                  }, {})

console.log({result: result.length, words: [...result.words]})
.as-console-wrapper {min-height:100%}


É uma virtude permitir que um noob também entenda o que está acontecendo :)
— mplungjan

Eu diria que este stackoverflow.com/a/60153437/295783 é mais legível. Algum comentário?
— mplungjan

3
Ternários aninhados são hediondos e perigosos. Sua busca por soluções de linha única fará o codificador depois que você se odeia muito :)
— mplungjan

Acho que reduzir não é muito bom para atualizar vários valores juntos (nesse caso, lengthe words).
— Gershom

1

Você pode fazer isso reduzindo a sentencematriz.

A vantagem dessa abordagem é que ela faz um loop na matriz apenas uma vez:

function longestWords(sentence) {
  return sentence.split(' ').reduce((output, word) => {
    if (word.length > output.length) {
      output.words = [word]
      output.length = word.length
    } else if (word.length === output.length) {
      output.words.push(word)
    }
    return output
  }, { length: 0, words: [] })
}
console.log(longestWords("The quick brown as bbbbbb fox jumped over the lazy dog"));

Ou, se você quiser filtrar palavras duplicadas, retorne um Set:

function longestWords(sentence) {
  return sentence.split(' ').reduce((output, word) => {
    if (word.length > output.length) {
      output.words.clear()
      output.length = word.length
    } 
    if (word.length >= output.length) {
      output.words.add(word)
    }
    return output
  }, { length: 0, words: new Set })
}
const words = longestWords("The quick brown as bbbbbb fox jumped over the jumped lazy dog")
console.log(words.length);
console.log(Array.from(words.words)) //Just to make StackSnippets console show the Set's entries


Esta é a redução mais legível publicada até agora
— mplungjan 10/02

Só pode votar uma vez. Grandes exemplos
— mplungjan

0

O que você pode fazer é verificar se o comprimento da palavra é maior ou igual ao comprimento do primeiro item da matriz (Todos os itens da matriz devem ter o mesmo comprimento).

Nesse caso, verifique se é maior. Se isso for verdade, defina a matriz com essa palavra, porque você encontrou uma palavra que era maior que as palavras da matriz. Caso contrário, adicione-o à matriz de palavras que têm o maior tamanho.

function longestWord(sentence) {
  sentence = sentence.split(' ');
  let theWord = sentence[0];
  var longest = 0;
  for (let i = 0; i < sentence.length; i++) {
    if (sentence[i] != "") {
      if (sentence[i].length >= theWord[0].length) {
        if (sentence[i].length > theWord[0].length) {
          longest = sentence[i].length;
          theWord = [sentence[i]];
        } else {
          theWord.push(sentence[i])
        }
      }
    }
  }
  return {
    length: longest,
    actuallWord: theWord
  }
}
console.log(longestWord("The quick brown as bbbbbb fox jumped over the lazy dog"));


0

Também pode ser feito em uma única redução.
Iniciado com o objeto.

function longestWord(words) {
  return words
    .split(/\s+/)
    .reduce((acc, word) => {
  	if(word.length > acc.length) {
  		acc.length = word.length;
  		acc.words = [word];
  	}
  	else if (word.length === acc.length) {
  		acc.words.push(word);
  	}
  	return acc;
  }, {length:0, words:[]});
}

console.log(longestWord("The quick brown as bbbbbb fox jumped over the lazy dog"));


0

Essa abordagem não tem uma complexidade de tempo melhor do que as melhores respostas aqui, mas possui melhores coeficientes. (Ele apenas percorre a matriz de palavras uma vez, nenhuma função é chamada, exceto Array.prototype.push).

let allLongestItems = items => {
  let longest = [];
  let length = 0;
  for (let item of items) {
    let len = item.length;
    if (len === length) longest.push(item)
    else if (len > length) { longest = [ item ]; length = len; }
  }
  return { items: longest, length };
};

let str = 'The quick brown as bbbbbb fox jumped over the lazy dog';
console.log(allLongestItems(str.split(' ')));

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.