Znajdowanie najdłuższego ciągu w tablicy

85

Czy istnieje krótki sposób na znalezienie najdłuższego ciągu w tablicy ciągów?

Coś jak arr.Max(x => x.Length);?

Neir0
źródło

Odpowiedzi:

198

Dostępne od Javascript 1.8 / ECMAScript 5 i dostępne w większości starszych przeglądarek :

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

W przeciwnym razie bezpieczna alternatywa:

var longest = arr.sort(
    function (a, b) {
        return b.length - a.length;
    }
)[0];
zamrozić
źródło
co się stanie, jeśli istnieją 2 lub więcej ciągów tego samego rozmiaru, a wynikiem powinna być tablica? Redukcja nie zadziała w takim przypadku i musisz powtórzyć pierwszy wynik.
Gismo Ranas
@GismoRanas To inne pytanie i nadal możesz użyć reducefunkcji wywołania zwrotnego, która zwraca tablicę.
deceze
36

Nowa odpowiedź na stare pytanie: w ES6 możesz zrobić krócej:

Math.max(...(x.map(el => el.length)));
Dávid Veszelovszki
źródło
7
Zwraca najdłuższy ciąg, a nie najdłuższy ciąg.
Mikemike
Inną rzeczą, na którą należy zwrócić uwagę, jest to, że spowoduje to dwukrotne przejrzenie kolekcji, ponieważ O(n^2)większość innych opcji przejdzie przez kolekcję tylko raz O(n). Niestandardowe komparatory mogą sortnawet używaćO(log(n))
CTS_AE
2
@CTS_AE Te dwa przejścia są niezależne, więc myślę, że tak O(n) + O(n) = O(n)nie jest O(n^2).
Joshua Breeden
@JoshuaBreeden Tak, wierzę, że masz rację w tej sprawie 👍
CTS_AE
28

Zrobiłbym coś takiego

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

Jason Gennaro
źródło
2
To jest najlepsze, ponieważ nie wpływa na twoją tablicę. Natomiast jeśli posortujesz (jak w wybranej odpowiedzi), twoja tablica zostanie posortowana, a czasami tego nie chcesz. +1, dzięki
thatOneGuy
4
var arr = [ 'fdgdfgdfg', 'gdfgf', 'gdfgdfhawsdgd', 'gdf', 'gdfhdfhjurvweadsd' ];
arr.sort(function (a, b) { return b.length - a.length })[0];
katspaugh
źródło
4

Korzystanie z Array.prototype - (sortowanie jest podobne do tego, co opublikowali @katsPaugh i @deceze, gdy grałem na skrzypcach)

DEMO TUTAJ

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());    
mplungjan
źródło
4

Zapewniam podejście funkcjonalne + rekurencyjne. Zobacz komentarze, aby zrozumieć, jak to działa:

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)

Matías Fidemraizer
źródło
jakiś pomysł, dlaczego to nie działa dla mnie? const longestRec = longestWord => ([nextWord, ... words]) => ^ TypeError: undefined nie jest funkcją
duke
@duke Rzucę okiem, ale domyślam się, co kryje się za tym problemem.
Matías Fidemraizer
@duke BTW, czy możesz podać mi dane wejściowe? czy używasz kodu tak jak jest ?
Matías Fidemraizer
patrz poniżej. ale nawet pozornie się nie kompiluje. ale masz rację: używanie tylko twojego kodu działa dobrze .... 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"}};
książę
przepraszam, że przeszkadzam, myślałem, że się nie skompilował. Nie mam tablicy.
książę
3

Widzę najkrótsze rozwiązanie

function findLong(s){
  return Math.max.apply(null, s.split(' ').map(w => w.length));
}
Giancarlo Ventura
źródło
1
Wolę ten, choć może nie jest najszybszy
guhur
1
to daje długość, ale nie słowo
brk
3

Może nie najszybszy, ale z pewnością całkiem czytelny:

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"

Funkcja tablicowa forEach jest obsługiwana od IE9 + .

Niels van Reijmersdal
źródło
3

W ES6 może to być osiągnięte za pomocą reduce()połączenia w O(n)złożoności, w przeciwieństwie do rozwiązań wykorzystujących sort()który jest O(nlogn):

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

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

Alex Lomia
źródło
1
Mam nadzieję, że więcej osób przewinie tak daleko, bo taka powinna być akceptowana odpowiedź. Jeśli z jakiegoś powodu potrzebujesz składni ES5 i nie możesz użyć funkcji grubej strzałki (smutna twarz), możesz to zrobić:arr.reduce(function(savedText, text) { return text.length > savedText.length ? text : savedText; }, '');
maxshuty
2

Zainspirowała mnie funkcja Jasona i dokonałem w niej niewielkich ulepszeń, w wyniku czego znalazłem dość szybką wyszukiwarkę:

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

Wyniki dotyczące prędkości: http://jsperf.com/longest-string-in-array/7

Timo Kähkönen
źródło
1

Zrobię coś takiego:

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");
Siawash Kasra
źródło
1

Jeśli twój ciąg jest już podzielony na tablicę, nie będziesz potrzebować podzielonej części.

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");
Andy Smith
źródło
1

Jeśli spodziewasz się więcej niż jednego maksimum, zadziała to:

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

Używa lodash i zwraca tablicę.

Gismo Ranas
źródło
0
var longest = (arr) => {
  let sum = 0
  arr.map((e) => {
    sum = e.length > sum ? e.length : sum
  })
  return sum
}

to może być praca

Jack Chen
źródło
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");
Barnet
źródło
Czy to dodaje coś do już obszernej listy istniejących odpowiedzi? Nie.
luk2302
0

Z obsługą ES6 również zduplikowany ciąg

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))
Taha Azzabi
źródło
0

Nowoczesne przeglądarki obsługują for...ofpętlę. Najszybszy i najkrótszy sposób rozwiązania tego problemu w Chrome, Safari, Edge i Firefox jest również najwyraźniejszy:

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

W IE możesz użyćArray.forEach ; to wciąż szybsze i wyraźniejsze niż sortowanie lub zmniejszanie tablicy.

var largest = '';
arr.forEach(function(item) {
  if (item.length > largest.length) largest = item
});
Dan Fabulich
źródło
0

To jest moje proste rozwiązanie

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])
Alex Irabor
źródło
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;
}
EMATade
źródło
2
Chociaż ten kod może rozwiązać problem z PO, najlepiej jest dołączyć wyjaśnienie, w jaki sposób Twój kod rozwiązuje problem PO. W ten sposób przyszli odwiedzający mogą uczyć się z Twojego postu i zastosować go do własnego kodu. SO nie jest usługą programistyczną, ale źródłem wiedzy. Ponadto istnieje większe prawdopodobieństwo, że wysokiej jakości, kompletne odpowiedzi zostaną poparte. Te funkcje, wraz z wymogiem, aby wszystkie posty były niezależne, są jednymi z mocnych stron SO jako platformy, która odróżnia ją od forów. Możesz edytować, aby dodać dodatkowe informacje i / lub uzupełnić wyjaśnienia o dokumentację źródłową.
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);
Ash Khan
źródło
lub bardziej przejrzysty sposób przy użyciu funkcji Arrow: var findLongestWord = function (array) {var longest = array.reduce ((a, b) => {return (a.length> b.length)? a: b;}); wrócić najdłużej; }
Ash Khan