¿Cómo puedo encontrar las palabras más largas en la cadena y devolverlas (excluyendo duplicados) junto con la longitud máxima?

8

Sé cómo puedo encontrar la palabra más larga en una cadena. Por ejemplo este código aquí. Pero aquí el problema es que la palabra "bbbbbb" se encuentra porque es la PRIMERA PALABRA MÁS LARGA DE LA cadena, después de eso con 6 caracteres también tenemos la palabra "saltó". Mi pregunta es cómo puedo encontrar en este caso y la palabra "saltó", por lo que todos ellos no solo el primero.

ACTUALIZACIÓN: quiero una lista única, por lo que solo una de cada palabras

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"));

Trajce12
fuente
Intenta sentence.filter(w => w.length === longest)obtener una variedad de palabras con esa longitud.
Rafi
Puede intentar crear una matriz para contener las palabras más largas que agregue. Luego puede usar filter () o map () para evaluar la longitud y agregar a la matriz.
CoderLee
Ahora tiene dos respuestas con palabras únicas: Yevhen's y FZs
mplungjan

Respuestas:

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"));

Luis felipe De jesus Munoz
fuente
Agradable para obtener la longitud en una declaración. Necesito más porque .sort no devuelve la matriz
mplungjan
3
@LuisfelipeDejesusMunoz ¿Por qué no agregar una explicación de todos modos? Es bueno para otros lectores que encuentran esta respuesta. Además del OP.
CoderLee
@YevgenGorbunkov Su solución también es genial. Gracias compañero
Trajce12
La solución anterior no omite las palabras duplicadas y el algoritmo implementado no es óptimo, ya que requiere innecesariamente 2 pasadas a través de la matriz, mientras que el enfoque de una sola pasada puede obtener un rendimiento aproximadamente un 15% mejor incluso para una cadena de prueba tan corta.
Yevgen Gorbunkov
@YevgenGorbunkov Tienes razón sobre el rendimiento, pero no estoy seguro de si el OP quería obtener palabras únicas (esa parte fue editada en la pregunta por otros )
FZ
2

Puede adoptar un enfoque de bucle simple y verificar la longitud de cada palabra con la longitud de los acumuladores del primer elemento.

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"));

Nina Scholz
fuente
@mplungjan: Interesante cómo diferentes estilos atraen a diferentes personas. Encuentro esta una de las respuestas más fáciles de leer. Por supuesto, tal vez sea porque es similar a la respuesta que escribí ... pero no publiqué porque Nina me convenció.
Scott Sauyet
2

Puede hacerlo con Array.prototype.reduce()una sola pasada a través de la matriz (sin bucles adicionales para calcular la longitud máxima).

La idea es restablecer la matriz resultante con una sola palabra, una vez que su longitud excede las que se insertaron antes o anexar si la palabra actual tiene la misma longitud, o simplemente pasar de lo contrario:

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%}

Yevgen Gorbunkov
fuente
Es una virtud permitir que un novato entienda lo que está pasando también :)
mplungjan
Yo diría que este stackoverflow.com/a/60153437/295783 es más legible. ¿Algún comentario?
mplungjan
3
Los terneros anidados son horribles y peligrosos. Su búsqueda de soluciones de línea única hará que el codificador después de que lo odie a lo grande :)
mplungjan
Creo que reducir no es demasiado bueno para actualizar varios valores juntos (en este caso, lengthy words).
Gershom
1

Puede hacerlo reduciendo la sentencematriz.

La ventaja de este enfoque es que se repite sobre la matriz solo una 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"));

O, si desea filtrar palabras duplicadas, puede devolver un Seten su lugar:

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

FZs
fuente
Esta es la reducción más legible publicada hasta ahora
mplungjan
Solo puede votar una vez. Grandes ejemplos
mplungjan
0

Lo que puede hacer es verificar si la longitud de la palabra es mayor o igual que la longitud del primer elemento de la matriz (Todos los elementos de la matriz deben tener la misma longitud).

Si es así, verifique si es mayor. Si eso es cierto, establezca la matriz en esa palabra, porque encontró una palabra que era más grande que las palabras en la matriz. De lo contrario, agréguelo al conjunto de palabras que tienen la mayor longitud.

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"));

JSScratchDouble
fuente
0

También se puede hacer en una sola reducción.
Iniciado con el 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"));

LukStorms
fuente
0

Este enfoque no tiene una mejor complejidad temporal que las mejores respuestas aquí, pero tiene mejores coeficientes. (Solo recorre el conjunto de palabras una vez, no hay llamadas de función excepto 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(' ')));

Gershom
fuente