120

Is there a short way to find the longest string in a string array?

Something like arr.Max(x => x.Length);?

0

16 Answers 16

256

Available since Javascript 1.8/ECMAScript 5 and available in most older browsers:

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

Otherwise, a safe alternative:

var longest = arr.sort(
    function (a, b) {
        return b.length - a.length;
    }
)[0];
Sign up to request clarification or add additional context in comments.

2 Comments

what if there are 2 or more strings of the same size and the result should be an array? reduce won't work in that case and you have to iterate on the first result.
@GismoRanas That’s a different question, and you could still use reduce with a callback function that returns an array.
67

A new answer to an old question: in ES6 you can do shorter:

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

4 Comments

This returns the longest string's length, not the longest string.
Another thing to note is that this will traverse the collection twice being O(n^2) where most other options will only traverse the collection once O(n). Custom comparators may using sort may even be O(log(n))
@CTS_AE The two traversals are independent, so I think this is O(n) + O(n) = O(n), not O(n^2).
@JoshuaBreeden Yep I believe you are correct on that one 👍
32

I would do something like this

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

2 Comments

This is the best one as it doesn't effect your array. Whereas if you sort (as in the chosen answer) your array gets sorted, when sometimes you dont want that. +1, thanks
Wondering why you're redeclaring var lgth within the for-loop? Doing this without redeclaring lgth gives me the correct answer. However, I changed all var's to let's in my own version.
8

Maybe not the fastest, but certainly pretty readable:

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"

The array function forEach has been supported since IE9+.

Comments

8

In ES6 this could be accomplished with a reduce() call in O(n) complexity as opposed to solutions using sort() which is O(nlogn):

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

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

6 Comments

I hope more people scroll down this far, because this should be the accepted answer. If for some reason you need ES5 syntax and can't use the fat arrow function (sad face), you can do this: arr.reduce(function(savedText, text) { return text.length > savedText.length ? text : savedText; }, '');
@maxshuty no need to scroll, this provides the same solution as the accepted answer posted 9 years earlier.
@miken32 originally the accepted answer was using sort, which is suboptimal, but recently it’s been edited I see
@miken32 how so? The original answer was posted in 2011 and it was edited in 2020
Idk what your point is, honestly. The revisions clearly say, that the edit was made on Nov 7, 2020
|
6
var arr = [ 'fdgdfgdfg', 'gdfgf', 'gdfgdfhawsdgd', 'gdf', 'gdfhdfhjurvweadsd' ];
arr.sort(function (a, b) { return b.length - a.length })[0];

Comments

4

Here input is an Array of strings

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

Comments

2

I was inspired of Jason's function and made a little improvements to it and got as a result rather fast finder:

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

Speed results: http://jsperf.com/longest-string-in-array/7

Comments

2

I provide a functional+recursive approach. See comments to understand how it works:

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)

7 Comments

any idea why this does not work for me? const longestRec = longestWord => ([nextWord, ...words]) => ^ TypeError: undefined is not a function
@duke I'll take a look, but I guess what's behind the issue.
@duke BTW, can you give me the input? are you using the code as is?
see below. but it does not even compile seemingly. but you are right: using only your code works fine.... 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" } };
sorry for bothering you, I thought it didn't compile. I do not have an array.
|
1

I see the shortest solution

function findLong(s){
  return Math.max.apply(null, s.split(' ').map(w => w.length));
}

2 Comments

I prefer that one, though it might not be the fastest one
this gives length but not the word
1

If your string is already split into an array, you'll not need the split part.

function findLongestWord(str) {
  str = str.split(' ');
  var longest = 0;

  for(var i = 0; i < str.length; i++) {
     if(str[i].length >= longest) {
       longest = str[i].length;
        } 
     }
  return longest;
}
findLongestWord("The quick brown fox jumped over the lazy dog");

Comments

1

In case you expect more than one maximum this will work:

_.maxBy(Object.entries(_.groupBy(x, y => y.length)), y => parseInt(y[0]))[1]

It uses lodash and returns an array.

Comments

1

With ES6 and it support a duplicate string

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

Comments

1

I would do something like this:

function findLongestWord(str) {
   var array = str.split(" ");
   var maxLength=array[0].length;
   for(var i=0; i < array.length; i++ ) {
      if(array[i].length > maxLength) maxLength = array[i].length
   }
 return maxLength;
}

findLongestWord("What if we try a super-long word such as otorhinolaryngology");

Comments

0

Modern browsers support a for...of loop. The fastest and shortest way to solve this problem in Chrome, Safari, Edge, and Firefox is also the clearest:

let largest = '';
for (let item of arr) {
  if (item.length > largest.length) largest = item
}

In IE, you can use Array.forEach; that's still faster and clearer than sorting or reducing the array.

var largest = '';
arr.forEach(function(item) {
  if (item.length > largest.length) largest = item
});

Comments

0

If you want to know the INDEX of the longest item:

var longest = arr.reduce(
        (a, b, i) => arr[a].length < b.length ? i : a,
        0
    );

(which can be a one-liner for those that love that stuff.... but it's split up here for readabilty)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.