107

I have a structure like this:

<ul>
  <li>text1</li>
  <li>text2</li>
  <li>text3</li>
</ul>

How do I use javascript or jQuery to get the text as an array?

['text1', 'text2', 'text3']

My plan after this is to assemble it into a string, probably using .join(', '), and get it in a format like this:

'"text1", "text2", "text3"'
Christian Oudard
  • 48,140
  • 25
  • 66
  • 69

6 Answers6

146
var optionTexts = [];
$("ul li").each(function() { optionTexts.push($(this).text()) });

...should do the trick. To get the final output you're looking for, join() plus some concatenation will do nicely:

var quotedCSV = '"' + optionTexts.join('", "') + '"';
Shog9
  • 156,901
  • 35
  • 231
  • 235
  • 2
    Does jQuery guarantee an order to the elements returned by the query? I would assume that the order returned is the same as the ordering in the DOM (ie text1, text2, text3), but I don't know what to look for in the documentation to see if this is true. – styfle Dec 23 '11 at 01:08
  • 2
    I've never seen it traverse the DOM in any other way that normal reading order. So although I can't prove it, I would bet the farm that it alwaays traverses the DOM top to bottom :) – Flater Aug 08 '12 at 08:35
  • Isn't $.each considered to have bad performance? If yes, is there any other way to do it? – Daniel Nov 01 '13 at 15:40
  • How many list items do you have that this is an issue, @Daniel? Yeah, there are other ways to do the same thing (you could use $.map() to generate the array in one go), but they amount to the same thing. – Shog9 Nov 01 '13 at 16:01
  • @Shog9: I wish to push a dictionary to the list taking values from two different columns from each rows of a table. Isn't there easier way to do that? Thanks in advance. – ln2khanal Dec 06 '13 at 15:54
  • You should post that as a separate question, @ln2khanal, and include an example of what you're looking to accomplish. – Shog9 Dec 06 '13 at 15:56
73

Without redundant intermediate arrays:

var arr = $('li').map(function(i,el) {
    return $(el).text();
}).get();

See jsfiddle demo

Clayton
  • 392
  • 1
  • 3
  • 17
kimstik
  • 1,611
  • 2
  • 15
  • 14
15

And in clean javascript:

var texts = [], lis = document.getElementsByTagName("li");
for(var i=0, im=lis.length; im>i; i++)
  texts.push(lis[i].firstChild.nodeValue);

alert(texts);
roenving
  • 2,560
  • 14
  • 14
14

kimstik was close, but not quite.

Here's how to do it in a convenient one-liner:

$.map( $('li'), function (element) { return $(element).text() });

Here's the full documentation for jQuery's map function, it's quite handy: http://api.jquery.com/jQuery.map/

Just to answer fully, here's the complete functionality you were looking for:

$.map( $('li'), function (element) { return $(element).text() }).join(', ');
Cybolic
  • 245
  • 2
  • 7
  • I just saw this here (http://stackoverflow.com/questions/4856283/jquery-collect-value-of-list-items-and-place-in-array) and was gonna repost since it's a great trick to know – SeanDowney Aug 15 '12 at 19:16
  • My way should be little bit faster.. or not? – kimstik Sep 21 '16 at 07:51
  • 1
    kimstik, according to Benchmark.js, my function call does 11,252 / 9,685 ops/sec for Opera and Chrome respectively, whereas the method call you posted does 9,666 / 9,083 ops/sec on a list of 40 items. I think the difference comes from the conversion from jQuery element list to Array in your example, if that helps. They're very close, so pick whichever suits your coding style better :) – Cybolic Sep 22 '16 at 20:04
6
var arr = new Array();

$('li').each(function() { 
  arr.push(this.innerHTML); 
})
Dave Ward
  • 59,815
  • 13
  • 117
  • 134
  • 1
    Instead of relying on innerHTML, you should change "this" to a jQuery object and use the jQuery native text method. $(this).text() – Nathan Strutz Oct 29 '08 at 14:49
  • 3
    why? eventually $(this).html() will use the native method – Khodor Jul 21 '10 at 09:00
  • In this case it's better to use [] instead of the new Array() - [What’s the difference](http://stackoverflow.com/a/1273936/3183606) – krypru Feb 09 '17 at 14:24
3

You may do as follows. one line of code will be enough

  • let array = $('ul>li').toArray().map(item => $(item).html());
  • Get the interested element

    1. get children

    2. get the array from toArray() method

    3. filter out the results you want

let array = $('ul>li').toArray().map(item => $(item).html());
console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li>text1</li>
  <li>text2</li>
  <li>text3</li>
</ul>
noone
  • 6,168
  • 2
  • 42
  • 51