在数组中找到最长的字符串

114

有没有一种简洁的方法来查找字符串数组中最长的字符串?

类似于arr.Max(x => x.Length);这样的东西?

16个回答

250

Javascript 1.8/ECMAScript 5 起可用,并且大多数旧版浏览器也支持 reduce 方法:

var longest = arr.reduce(
    function (a, b) {
        return a.length > b.length ? a : b;
    }
);

否则,一个安全的替代方案:

var longest = arr.sort(
    function (a, b) {
        return b.length - a.length;
    }
)[0];

如果有两个或多个相同大小的字符串,结果应该是一个数组怎么办?在这种情况下,reduce将无法工作,您必须迭代第一个结果。 - Gismo Ranas
@GismoRanas 这是一个不同的问题,你仍然可以使用带有返回数组的回调函数的 reduce - deceze

62

一道老问题的新解: 在ES6中你可以使用更简洁的写法:

Math.max(...(x.map(el => el.length)));

29
这将返回最长字符串的长度,而不是最长的字符串本身。 - Michał Terczyński
另一个需要注意的事情是,这将对集合进行两次遍历,其时间复杂度为O(n^2),而其他大多数选项只需遍历一次集合即可达到O(n)的复杂度。使用 sort 的自定义比较器甚至可以达到O(log(n))的复杂度。 - CTS_AE
9
这两个遍历是独立的,所以我认为这是 O(n) + O(n) = O(n),而不是 O(n^2) - Joshua Breeden
1
@JoshuaBreeden 没错,我相信你是正确的。 - CTS_AE

32

我会这样做

var arr = [
  'first item',
  'second item is longer than the third one',
  'third longish item'
];

var lgth = 0;
var longest;

for (var i = 0; i < arr.length; i++) {
  if (arr[i].length > lgth) {
    var lgth = arr[i].length;
    longest = arr[i];
  }
}

console.log(longest);


3
这是最好的选择,因为它不会影响你的数组。而如果你对数组进行排序(就像选定的答案一样),有时候你并不想要这样。+1,谢谢。 - thatOneGuy
想知道为什么在for循环内重新声明var lgth吗?如果不重新声明lgth,这样做会给我正确的答案。但是,在我的版本中,我将所有的var都改成了let - HappyHands31

8
也许不是最快的,但肯定很易读:
function findLongestWord(array) {
  var longestWord = "";

  array.forEach(function(word) {
    if(word.length > longestWord.length) {
      longestWord = word;
    }
  });

  return longestWord;
}

var word = findLongestWord(["The","quick","brown", "fox", "jumped", "over", "the", "lazy", "dog"]);
console.log(word); // result is "jumped"

自IE9+开始,数组函数forEach已被支持。


7
在ES6中,可以使用 reduce() 方法以 O(n) 的时间复杂度来实现这一点,而不是使用 sort() 方法,其时间复杂度为 O(nlogn)

const getLongestText = (arr) => arr.reduce(
  (savedText, text) => (text.length > savedText.length ? text : savedText),
  '',
);

console.log(getLongestText(['word', 'even-longer-word', 'long-word']))


1
我希望更多人能够滚动到这里,因为这应该是被接受的答案。如果出于某种原因您需要ES5语法并且无法使用箭头函数(伤心脸),您可以执行以下操作:arr.reduce(function(savedText, text) { return text.length > savedText.length ? text : savedText; }, ''); - maxshuty
1
@maxshuty 不需要滚动,这提供了与9年前发布的被接受答案相同的解决方案。 - miken32
1
@miken32 最初被接受的答案使用了排序,这是次优的,但最近已经被编辑过了。 - Alex Lomia
不,这是在原始答案发布后10分钟进行编辑添加的。 - miken32
1
@miken32 怎么了?原始答案是在2011年发布的,2020年进行了编辑。 - Alex Lomia
1
老实说,我不知道你的观点是什么。修订版明确指出,编辑是在2020年11月7日进行的(https://imgur.com/a/w8L8RbH)。 - Alex Lomia

6
var arr = [ 'fdgdfgdfg', 'gdfgf', 'gdfgdfhawsdgd', 'gdf', 'gdfhdfhjurvweadsd' ];
arr.sort(function (a, b) { return b.length - a.length })[0];

4

这里 input 是一个字符串数组

function Max(input) {
   return input.reduce((a, b) => a.length <= b.length ? b : a)
}

2
我受到Jason函数的启发,对它进行了一些小改进,并得到了一个相当快速的查找器。
function timo_longest(a) {
  var c = 0, d = 0, l = 0, i = a.length;
  if (i) while (i--) {
    d = a[i].length;
    if (d > c) {
      l = i; c = d;
    }
  }
  return a[l];
}
arr=["First", "Second", "Third"];
var longest = timo_longest(arr);

速度测试结果: http://jsperf.com/longest-string-in-array/7


2

我提供了一种功能性+递归的方法。看看注释以了解它是如何工作的:

const input1 = ['a', 'aa', 'aaa']
const input2 = ['asdf', 'qwer', 'zxcv']
const input3 = ['asdfasdf fdasdf a sd f', ' asdfsdf', 'asdfasdfds', 'asdfsdf', 'asdfsdaf']
const input4 = ['ddd', 'dddddddd', 'dddd', 'ddddd', 'ddd', 'dd', 'd', 'd', 'dddddddddddd']

// Outputs which words has the greater length
// greatestWord :: String -> String -> String
const greatestWord = x => y => 
      x.length > y.length ? x : y
      
// Recursively outputs the first longest word in a series
// longestRec :: String -> [String] -> String
const longestRec = longestWord => ([ nextWord, ...words ]) =>
      //                                ^^^^^^^^^^^^
      // Destructuring lets us get the next word, and remaining ones!
      nextWord // <-- If next word is undefined, then it won't recurse.
        ? longestRec (greatestWord (nextWord) (longestWord)) (words) 
        : longestWord


// Outputs the first longest word in a series
// longest :: [String] -> String
const longest = longestRec ('')

const output1 = longest (input1)
const output2 = longest (input2) 
const output3 = longest (input3)
const output4 = longest (input4)

console.log ('output1: ', output1)
console.log ('output2: ', output2)
console.log ('output3: ', output3)
console.log ('output4: ', output4)


你有任何想法为什么这对我不起作用吗?const longestRec = longestWord => ([nextWord, ...words]) => ^ 类型错误:未定义的函数。 - duke
@duke 我会看一下,但我猜测问题背后的原因。 - Matías Fidemraizer
但是它似乎甚至无法编译。但你是对的:只使用你的代码就可以正常工作...let obj = { "HostName": { "Generated": "@logon", "Value": "openPI", "LastRun": "2018-11-15 07:57:50,186" }, "HostIp": { "Generated": "@cron", "Value": "192.168.178.70", "LastRun": "2018-11-15 02:49:23,961" }, "Release": { "Generated": "@cron", "Value": "Raspbian GNU/Linux 9 (stretch)", "LastRun": "2018-11-15 02:49:24,099" } }; - duke
@duke 没问题。当然,这种方法与数组相关联,绝无可能! - Matías Fidemraizer
数组包含空字符串时出现错误。 - customcommander
显示剩余2条评论

1

使用ES6并支持重复字符串

var allLongestStrings = arrayOfStrings => {
  let maxLng = Math.max(...arrayOfStrings.map( elem => elem.length))
  return arrayOfStrings.filter(elem => elem.length === maxLng)
}

let arrayOfStrings = ["aba", "aa", "ad", "vcd","aba"]
 
console.log(allLongestStrings(arrayOfStrings))

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