Пошук найдовшого рядка в масиві


84

Чи існує короткий спосіб знайти найдовший рядок у масиві рядків?

Щось на зразок arr.Max(x => x.Length);?

Відповіді:


194

Доступний з Javascript 1.8 / ECMAScript 5 і доступний у більшості старих браузерів :

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

що, якщо є 2 або більше рядків однакового розміру, і результатом повинен бути масив? У такому випадку функція зменшення не спрацює, і вам доведеться повторити перший результат.
Gismo Ranas

@GismoRanas Це вже інше питання, і ви все одно можете використовувати його reduceз функцією зворотного виклику, яка повертає масив.
обман

34

Нова відповідь на старе запитання: у ES6 ви можете зробити коротше:

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

7
Це повертає довжину найдовшого рядка, а не найдовшого рядка.
Mikemike

Інша річ, на яку слід звернути увагу, - це те, що колекція пройде колекцію двічі, O(n^2)коли більшість інших опцій пройде колекцію лише один раз O(n). Можливо, користувацькі порівняльники можуть sortнавіть використовуватиO(log(n))
CTS_AE,

27

Я б зробив щось подібне

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
Це найкращий, оскільки він не впливає на ваш масив. Тоді як якщо ви сортуєте (як у вибраній відповіді), ваш масив сортується, коли іноді ви цього не хочете. +1, спасибі
thatOneGuy

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

4

Використання Array.prototype - (сортування подібне до того, що опублікували @katsPaugh та @deceze, коли я робив скрипку)

ДЕМО ТУТ

var arr = [
    "2 --",
    "3 ---",
    "4 ----",
    "1 -",
    "5 -----"
];

Array.prototype.longest=function() {
    return this.sort(
      function(a,b) {  
        if (a.length > b.length) return -1;
        if (a.length < b.length) return 1;
          return 0
      }
    )[0];
}
alert(arr.longest());    

4

Я пропоную функціональний + рекурсивний підхід. Перегляньте коментарі, щоб зрозуміти, як це працює:

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 longthRec = longthWord => ([nextWord, ... слова]) => ^ TypeError: undefined не є функцією
герцог

@duke Я подивлюсь, але я здогадуюсь, що стоїть за цією проблемою.
Matías Fidemraizer

@duke BTW, ти можеш дати мені введення? ти використовуєш код як є ?
Matías Fidemraizer

Дивіться нижче. але навіть не складається, здавалося б. але ви маєте рацію: використання лише вашого коду працює нормально .... let obj = {"HostName": {"Generated": "@logon", "Value": "openPI", "LastRun": "2018-11- 15 07: 57: 50,186 "}," HostIp ": {" Створено ":" @cron "," Значення ":" 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"}};
герцог

вибачте, що турбую вас, я думав, що це не компіляція. У мене немає масиву.
герцог

3

Я бачу найкоротше рішення

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

1
Я віддаю перевагу такому, хоча це може бути не найшвидший
гухур

1
це дає довжину, але не слово
brk

3

Можливо, не найшвидший, але, звичайно, досить читабельний:

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"

Функція масиву forEach підтримується з IE9 + .


3

У 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

2

Мене надихнула функція Джейсона, я зробив її трохи вдосконалений і в результаті отримав досить швидкий пошук:

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


1

Я зроблю щось подібне:

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

1

Якщо ваш рядок уже розділений на масив, розділена частина вам не знадобиться.

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

1

Якщо ви очікуєте більше одного максимуму, це буде працювати:

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

Він використовує lodash і повертає масив.


0
var longest = (arr) => {
  let sum = 0
  arr.map((e) => {
    sum = e.length > sum ? e.length : sum
  })
  return sum
}

це може бути робота


0
function findLongestWord(str) {
  str = str.split(" ");
  var sorted = str.sort(function(prev,current){
    return prev.length - current.length;   
  });
  var index = sorted.length;
  str = sorted[index-1];
  return str;
}
findLongestWord("The quick brown fox jumped over the lazy dog");

Чи додає це щось до і без того широкого списку існуючих відповідей? Ні
luk2302

0

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

0

Сучасні браузери підтримують for...ofцикл. Найшвидший і найкоротший спосіб вирішити цю проблему в Chrome, Safari, Edge та Firefox також є найбільш зрозумілим:

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

В IE ви можете використовуватиArray.forEach ; це все одно швидше і зрозуміліше, ніж сортування або зменшення масиву.

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

0

Це моє просте рішення

var arr = ["you", "are", "the", "love", "of", "my", "life"];
var sorted = arr.sort(function (a, b){
     return b.length - a.length;
});

console.log(sorted[0])

0
function allLongestStrings(array) {
    const newArr=[];
    let temp =    Math.max(...(array.map(el => el.length)));    
     array.forEach(item => {
        if(temp == item.length){
          newArr.push(item);
        }
    });
    return newArr;
}

2
Хоча цей код може вирішити проблему OP, найкраще включити пояснення щодо того, як ваш код вирішує проблему OP. Таким чином, майбутні відвідувачі можуть вчитися на вашому дописі та застосовувати його до власного коду. SO - це не служба кодування, а ресурс для знань. Крім того, якісні, повні відповіді, швидше за все, проголосують. Ці особливості, поряд із вимогою, щоб усі дописи були автономними, є сильними сторонами SO як платформи, яка відрізняє його від форумів. Ви можете редагувати, щоб додати додаткову інформацію та / або доповнити свої пояснення вихідною документацією.
ysf

-1
var array = ["hello","falsey","undefined"];
var findLongestWord = function(array){
    var longest = array.reduce(function(a,b){
    return (a.length > b.length) ? a : b;
  });
    return longest;
}
findLongestWord(array);

чи більш чистий спосіб із використанням функції стрілки: var findLongestWord = function (array) {var longth = array.reduce ((a, b) => {return (a.length> b.length)? a: b;}); повернення найдовше; }
Ash Khan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.