882

I have a comma-separated string that I want to convert into an array, so I can loop through it.

Is there anything built-in to do this?

For example, I have this string

var str = "January,February,March,April,May,June,July,August,September,October,November,December";

Now I want to split this by the comma, and then store it in an array.

Inigo
  • 12,186
  • 5
  • 41
  • 70
Blankman
  • 259,732
  • 324
  • 769
  • 1,199
  • 2
    possible duplicate of [How can I parse a CSV string with Javascript?](http://stackoverflow.com/questions/8493195/how-can-i-parse-a-csv-string-with-javascript) – gcochard Jan 14 '13 at 17:28
  • 4
    Regarding duplicate: this predates the referenced question by 18 months. If anything, the other is not only a dupe but offers an extremely complicated solution for a very simple problem due to the regex requirement – NotMe Jan 14 '13 at 17:30

19 Answers19

1464
const array = string.split(',');

MDN reference, mostly helpful for the possibly unexpected behavior of the limit parameter. (Hint: "a,b,c".split(",", 2) comes out to ["a", "b"], not ["a", "b,c"].)

Community
  • 1
  • 1
Matchu
  • 83,922
  • 18
  • 153
  • 160
  • 9
    While `split` will work fine if you are sure you have elements in `array`, if you're expecting data from a server / database you will run into trouble since `''.split(',')` has a `length === 1` IE: `''.split(',') === ['']` – Vlad Goran Aug 02 '16 at 15:49
  • this is for comma separated but what if i want to separate with 'and' ',' '&' ?? how will you do it – Prasanna Nov 13 '18 at 09:15
  • What if there is more then one sting and some strings have no comma. How can i retirn one member arrays? – Razvan Zamfir May 16 '19 at 07:09
  • a way of solving empty string element when ''.split(',') === [''] is filtering string.split(',').filter(e => e !== '') – Gabriel Linassi Mar 24 '20 at 04:58
  • @VladGoran I am trying to split the values before using $in operator with mongo. It does not work. Could you help? – IronmanX46 Jul 07 '21 at 11:28
146

Watch out if you are aiming at integers, like 1,2,3,4,5. If you intend to use the elements of your array as integers and not as strings after splitting the string, consider converting them into such.

var str = "1,2,3,4,5,6";
var temp = new Array();
// This will return an array with strings "1", "2", etc.
temp = str.split(",");

Adding a loop like this,

for (a in temp ) {
    temp[a] = parseInt(temp[a], 10); // Explicitly include base as per Álvaro's comment
}

will return an array containing integers, and not strings.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pop
  • 3,464
  • 3
  • 26
  • 43
  • 49
    Please note that parseInt() tries to guess the base unless you explicit set it, which can cause unexpected results when dealing with leading zeros (`"001,002,003..."`). Compare `parseInt('010')` with `parseInt('010', 10)`. – Álvaro González Dec 14 '10 at 16:04
  • 2
    +1 This example is more clear, demonstrating that string is not a static object but in fact the variable that is the string. – K0D4 Oct 10 '13 at 20:11
  • 8
    The `map` function can be used to do the integer parsing in one line: `str.split(',').map(parseInt)` – Jud Mar 06 '14 at 21:12
  • My first number always still has a quote character in front. ```""25342","56743","457863""``` becomes ```"25342,56743,457863"``` This makes parseInt unable to number-ise the first number ```"25342``` giving me NaN. I strip them now first before parseInting (in a for loop, not for..in; does that matter?). Would be nice to avoid that extra line if possible. – stommepoes Oct 16 '14 at 10:21
  • Seems like you are forcing a set of strings "25342", "56743", "457863" to wrap into another set of "" which gives you a string of strings. Mind looking at this extra-wrapping first? – pop Oct 16 '14 at 14:02
  • 1
    This is not the most efficient solution. According to my experiments under Chrome 49. JSON.parse('[' + str + ']') is 40% faster than this solution. – Yao Apr 19 '16 at 18:41
  • @Yao your solution won't work `JSON.parse('['1,2,3,4,5']');` is not going to magically separate 1 2 3 4 5 – Emilio Apr 03 '18 at 01:09
  • @ÁlvaroGonzález using Number('010') doesn't have the problem you describe. Also other issue can be handled by upgrading your use of `split`. See https://stackoverflow.com/a/69966162/8910547 – Inigo Nov 14 '21 at 18:58
  • @Inigo This was written 11 years ago. Things have changed. ECMAScript 5 actually disallows interpreting strings with leading zero as octal. ([Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#octal_interpretations_with_no_radix)). – Álvaro González Nov 15 '21 at 09:22
  • @ÁlvaroGonzález, sure, but it is important to update/clarify because your comment has 47 upvotes. People see that, not the date. – Inigo Nov 15 '21 at 10:20
38

Hmm, split is dangerous IMHO as a string can always contain a comma. Observe the following:

var myArr = "a,b,c,d,e,f,g,','";
result = myArr.split(',');

So how would you interpret that? And what do you want the result to be? An array with:

['a', 'b', 'c', 'd', 'e', 'f', 'g', '\'', '\''] or
['a', 'b', 'c', 'd', 'e', 'f', 'g', ',']

Even if you escape the comma, you'd have a problem.

I quickly fiddled this together:

(function($) {
    $.extend({
        splitAttrString: function(theStr) {
            var attrs = [];

            var RefString = function(s) {
                this.value = s;
            };
            RefString.prototype.toString = function() {
                return this.value;
            };
            RefString.prototype.charAt = String.prototype.charAt;
            var data = new RefString(theStr);

            var getBlock = function(endChr, restString) {
                var block = '';
                var currChr = '';
                while ((currChr != endChr) && (restString.value !== '')) {
                    if (/'|"/.test(currChr)) {
                        block = $.trim(block) + getBlock(currChr, restString);
                    }
                    else if (/\{/.test(currChr)) {
                        block = $.trim(block) + getBlock('}', restString);
                    }
                    else if (/\[/.test(currChr)) {
                        block = $.trim(block) + getBlock(']', restString);
                    }
                    else {
                        block += currChr;
                    }
                    currChr = restString.charAt(0);
                    restString.value = restString.value.slice(1);
                }
                return $.trim(block);
            };

            do {
                var attr = getBlock(',', data);
                attrs.push(attr);
            }
            while (data.value !== '')
                ;
            return attrs;
        }
    });
})(jQuery);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Justme
  • 381
  • 3
  • 3
  • 2
    This works great with numbers also and we don't have to run a separate parseInt loop for them as mentioned in another answer below. This is real deep thinking. Appreciate it very much and I think the best answer among all !! – Anmol Saraf Oct 24 '12 at 23:47
  • Your code is useful, but you didn't answer the question: *"Is there anything built-in to do this?"* Of course we can write a custom function as you did, or even better import one of the many existing libraries already written and well tested (e.g. [jquery-csv](https://www.jqueryscript.net/other/Parsing-Displaying-CSV-Files-jQuery.html)). But is there something ***built in?*** – Inigo Feb 23 '22 at 05:02
31

The split() method is used to split a string into an array of substrings, and returns the new array.

var array = string.split(',');
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
Jakkwylde
  • 1,304
  • 9
  • 16
  • what would the outcome be? for example if i have var a = "hello,world,baby"; and var array = a.split(','); --> would my array look like this: array = ["hello","world","baby"]; ?? – pivotal developer Mar 12 '11 at 07:29
  • 1
    Yes, that is correct. The resulting array would be just as you mention. – Jakkwylde Mar 23 '11 at 23:54
20

Upgraded str.split(',')

The simple str.split(',') doesn't have much smarts. Here are some upgrades for different needs. You can customize the functionality to your heart's content.

const str = "a, b,c,  d  ,e  ,f,,g"
const num = "1, 2,3,  4  ,5  ,6,,7.495"
const mix = "a, 2,3,  d  ,5  ,f,,7.495,g"

console.log(    str.split(',')
) // spaces NOT trimmed, empty values included
  // ["a", " b", "c", "  d  ", "e  ", "f", "", "g"] 

console.log(    str.split(/[ ,]+/)
) // spaces trimmed, empty values skipped
  // ["a", "b", "c", "d", "e", "f", "g"] 

console.log(    str.split(/\s*,\s*/)
) // spaces trimmed, empty values NOT skipped
  // ["a", "b", "c", "d", "e", "f", "", "g"]

console.log(    num.split(',').map(Number)
) // numbers, empty values default to zero
  // [1, 2, 3, 4, 5, 6, 0, 7.495] 

console.log(    num.split(/[ ,]+/).map(Number)
) // numbers, skips empty values
  // [1, 2, 3, 4, 5, 6, 7.495]

console.log(    mix.split(/\s*,\s*/)
                .map(x => (x === '') ? '' : (isNaN(Number(x)) ? x : Number(x)) )
) // mixed values, empty values included
  // ["a", 2, 3, "d", 5, "f", "", 7.495, "g"]

Using JSON.parse

It may feel like a bit of a hack, but it's simple and highly optimized by most Javascript engines.

It has some other advantages such as support for nested lists. But there are disadvantages, such as requiring the input to be properly formatted JSON.

By using string.replace similar to how I used string.split above, you can fix the input. In the first two examples below, I customize how I want empty values handled:

const num = "1, 2,3,  4  ,5  ,6,,7.495"
const mix = "a, 2,3,  d  ,5  ,f,7.495,g"

console.log(    JSON.parse('['+num.replace(/,\s*,/,',0,')+']')
) // numbers, empty values default to zero
  // [1, 2, 3, 4, 5, 6, 0, 7.495]

console.log(    JSON.parse('['+num.replace(/,\s*,/,',')+']')
) // numbers, skips empty values
  // [1, 2, 3, 4, 5, 6, 7.495]

console.log(    JSON.parse('['+mix.replace(/(^|,)\s*([^,]*[^0-9, ][^,]*?)\s*(?=,|$)/g,'$1"$2"')+']') 
) // mixed values, will ERROR on empty values
  // ["a", 2, 3, "d", 5, "f", "7.495", "g"]  
Inigo
  • 12,186
  • 5
  • 41
  • 70
19

Note that the following:

var a = "";
var x = new Array();
x = a.split(",");
alert(x.length);

will alert 1

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1386213
  • 951
  • 9
  • 17
15

Pass your comma-separated string into this function and it will return an array, and if a comma-separated string is not found then it will return null.

function splitTheString(CommaSepStr) {
    var ResultArray = null;

    // Check if the string is null or so.
    if (CommaSepStr!= null) {

        var SplitChars = ',';

        // Check if the string has comma of not will go to else
        if (CommaSepStr.indexOf(SplitChars) >= 0) {
            ResultArray = CommaSepStr.split(SplitChars);

        }
        else {

            // The string has only one value, and we can also check
            // the length of the string or time and cross-check too.
            ResultArray = [CommaSepStr];
        }
    }
    return ResultArray;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BJ Patel
  • 6,148
  • 11
  • 47
  • 81
  • 3
    Rather than only post a block of code, please *explain* why this code solves the problem posed. Without an explanation, this is not an answer. – Martijn Pieters Nov 29 '12 at 10:12
  • 1
    This is the most correct solution if you aren't sure the string will contain your split value. This function will keep the split method from erroring out if the string doesn't have a comma (given the above example). – CoryDorning Mar 11 '13 at 19:46
  • 1
    Note: functions that start with a capital letter are, most of the time, designed to be invoked. best to use lower case letters on functions that are not designed to be invoked. – Jsterman Apr 09 '13 at 15:17
  • This failed for me when I had only one value with no commas. Added `else { ResultArray = [CommaSepStr]; }` after the second `if` – MomasVII Feb 06 '20 at 04:18
12

Here is a function that will convert a string to an array, even if there is only one item in the list (no separator character):

function listToAray(fullString, separator) {
  var fullArray = [];

  if (fullString !== undefined) {
    if (fullString.indexOf(separator) == -1) {
      fullArray.push(fullString);
    } else {
      fullArray = fullString.split(separator);
    }
  }

  return fullArray;
}

Use it like this:

var myString = 'alpha,bravo,charlie,delta';
var myArray = listToArray(myString, ',');
myArray[2]; // charlie

var yourString = 'echo';
var yourArray = listToArray(yourString, ',');
yourArray[0]; // echo
Inigo
  • 12,186
  • 5
  • 41
  • 70
Kabb5
  • 3,760
  • 2
  • 33
  • 55
  • 5
    No error is thrown if the separator is not found: `'echo'.split(',')` returns `['echo']`, and `''.split(',')` returns `['']`. You _will_ get an error if you call `x.split(',')` when `x` is not a string (including when `x` is _undefined_ or _null_), because there is no `split` function available for other types. – Joel Lee Oct 22 '13 at 23:16
  • Ah, I see that I was in fact trying to use `split` for an undefined object when I wrote up my listToArray function. Thanks for pointing that out... – Kabb5 Oct 23 '13 at 19:16
9
let str = "January,February,March,April,May,June,July,August,September,October,November,December"

let arr = str.split(',');

it will result:

["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

and if you want to convert following to:

["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

this:

"January,February,March,April,May,June,July,August,September,October,November,December";

use:

str = arr.join(',')
Mosbah
  • 1,347
  • 1
  • 14
  • 28
Mubeen Khan
  • 997
  • 1
  • 10
  • 11
8

Return function

var array = (new Function("return [" + str+ "];")());

Its accept string and objectstrings:

var string = "0,1";

var objectstring = '{Name:"Tshirt", CatGroupName:"Clothes", Gender:"male-female"}, {Name:"Dress", CatGroupName:"Clothes", Gender:"female"}, {Name:"Belt", CatGroupName:"Leather", Gender:"child"}';

var stringArray = (new Function("return [" + string+ "];")());

var objectStringArray = (new Function("return [" + objectstring+ "];")());

JSFiddle https://jsfiddle.net/7ne9L4Lj/1/

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andi AR
  • 2,678
  • 2
  • 23
  • 28
  • 3
    text strings are having errors - SyntaxError: Unexpected identifier number strings are ok. eg. `var stringtext = "String, text, I, am"; var stringtextArray = (new Function("return [" + string text + "];")());` result is: SyntaxError: Unexpected identifier – nycdanie Mar 16 '16 at 22:54
6

I had a similar issue, but more complex as I needed to transform a CSV file into an array of arrays (each line is one array element that inside has an array of items split by comma).

The easiest solution (and more secure I bet) was to use PapaParse which has a "no-header" option that transform the CSV file into an array of arrays, plus, it automatically detected the "," as my delimiter.

Plus, it is registered in Bower, so I only had to:

bower install papa-parse --save

And then use it in my code as follows:

var arrayOfArrays = Papa.parse(csvStringWithEnters), {header:false}).data;

I really liked it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Diego Pamio
  • 1,377
  • 13
  • 21
3

A good solution for that:

let obj = ['A','B','C']

obj.map((c) => { return c. }).join(', ')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Manspof
  • 598
  • 26
  • 81
  • 173
3

As @oportocala mentions, an empty string will not result in the expected empty array.

So to counter, do:

str
.split(',')
.map(entry => entry.trim())
.filter(entry => entry)

For an array of expected integers, do:

str
.split(',')
.map(entry => parseInt(entry))
.filter(entry => typeof entry ==='number')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CyberProdigy
  • 737
  • 9
  • 20
3

Easiest way to do it:

let myStr = '1, 2, 3, 4, 5, 7, 8';

const stringToArr = (myStr) => {
    return myStr.split(',').map(x => x.trim());
};
Radim Šafrán
  • 463
  • 7
  • 16
1

Shortest

str.split`,`

var str = "January,February,March,April,May,June,July,August,September,October,November,December";

let arr = str.split`,`;

console.log(arr);
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
1
let myString = "January,February,March,April,May,June,July,August,September,October,November,December";
      const temp=myString .split(",");
      console.log(temp);

Output:-  ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

Very simple you can use the split default javascript function for this.

Force Bolt
  • 1,117
  • 9
  • 9
0

I made php script to convert string to array, and you can run it into your browser, so is easy

<form method="POST">
    <div>
        <label>String</label> <br>
        <input name="string" type="text">
    </div>
    <div style="margin-top: 1rem;">
        <button>konvert</button>
    </div>
</form>

<?php

$string = @$_POST['string'];

if ($string) {
    $result = json_encode(explode(",",$string));
    echo " '$result' <br>";
}
?>
Rahmad Al Habib
  • 300
  • 4
  • 7
0

If the user makes a typo by adding an extra space. You could use something like this.

tags: foo,  zar, gar
const stringToArr = (string) => {
  return string.trim.split(",");
};
-2

For an array of strings to a comma-separated string:

let months = ["January","Feb"];
let monthsString = months.join(", ");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Srikanth Gowda
  • 6,163
  • 7
  • 19
  • 34
  • 4
    That's the reverse of what they're asking for – camille Dec 05 '20 at 01:30
  • @camille i know that did u read the text i said "For an array of strings to a comma-separated string" – Srikanth Gowda Dec 15 '20 at 16:09
  • 3
    Yes, I did read the text of your answer, but I also read the text of the question. What you've provided is an answer to the opposite operation of what they're trying to do. It would be a fine answer to a question on joining an array, but that's not what this question is – camille Dec 15 '20 at 16:20