如何在字符串中找到最长的单词并将它们返回(不包括重复的),同时还要返回最大长度?

8

我知道如何在字符串中找到最长的单词。例如这段代码。但是问题在于单词“bbbbbb”被找到,因为它是字符串中第一个最长的单词。之后,长度为6的单词“jumped”也是最长的单词。我的问题是如何在这种情况下找到单词“jumped”,以及所有最长的单词,而不仅仅是第一个。

更新:我想要一个唯一的列表,所以每个单词只出现一次。

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


尝试使用 sentence.filter(w => w.length === longest) 来获取具有该长度的单词数组。 - Rafi
你可以尝试创建一个数组来保存你添加的最长单词。然后,你可以使用filter()或map()函数来计算长度并将其添加到数组中。 - CoderLee
你现在有两个带有独特单词的答案:Yevhen'sFZs - mplungjan
7个回答

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


很好的方法可以在一条语句中获取长度。我需要更多,因为.sort不会返回数组。 - mplungjan
3
为什么不添加解释呢?这对其他读者很有帮助,还有原问题的提出者。 - CoderLee
@YevgenGorbunkov,你的解决方案也很棒。谢谢伙计。 - Trajce12
@YevgenGorbunkov,您关于性能的观点是正确的,但我不确定 OP 是否想要获取唯一单词(该部分已由其他人编辑了问题)。 - FZs
@Gershom:你正在对比的3个代码片段返回了3个不同的结果。有效版本的基准测试应该是像这样的。然而,我的观点很简单:为解决这样的问题,2次遍历绝对是不必要的。你如何进行单次遍历取决于你自己,正如所说,对我来说,“for...”循环在美学上不值得它们可能提供的性能增益,我更喜欢高阶方法的外观、链式调用等方面。 - Yevhen Horbunkov
显示剩余3条评论

2
你可以使用Array.prototype.reduce()一次遍历数组来实现这个操作(不需要额外循环计算最大长度)。
思路是,当结果数组的长度超过之前插入的长度时,用一个单词重置该数组,或者在当前单词具有相同长度时追加,否则就跳过。

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


让新手也能理解正在发生的事情是一种美德 :) - mplungjan
我认为这个答案更易读:https://dev59.com/qbnoa4cB1Zd3GeqPLSpT#60153437。有什么评论吗? - mplungjan
3
嵌套三目运算符既难看又危险。追求单行解决方案会让你后面的程序员非常讨厌你 :) - mplungjan
我发现使用reduce函数无法很好地同时更新多个值(在这种情况下是lengthwords)。 - Gershom Maes

2
你可以采用单循环方法,并检查每个单词的长度,使用第一项的累加器长度。

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:有趣的是,不同的风格吸引不同的人。我发现这是最容易阅读的答案之一。当然,可能是因为它类似于我写的答案……但没有发布,因为Nina比我更快。 - Scott Sauyet

1
你可以通过减少 sentence 数组来实现它。

The advantage of this approach is that it loops over the array only once:

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

或者,如果你想要过滤掉重复的单词,你可以返回一个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


0
你可以检查单词的长度是否大于或等于数组中第一个项目的长度(数组中所有项目的长度应相同)。
如果是这样,那么再检查它是否更大。如果是真的,那么将该单词设置为数组,因为你找到了一个比数组中的单词更大的单词。否则,将其添加到具有最大长度的单词数组中。

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

也可以在单个reduce中完成。
以该对象为初始值。

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

这种方法的时间复杂度并不比这里最佳答案更好,但它确实有更好的系数。(它只循环遍历一次单词数组,除了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(' ')));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接