Mark Bell
Mark Bell

Reputation: 29785

Why does Array.concat produce a three element array when concatenating a two-element and three-element array of jQuery objects?

I have a form with two fixed input elements, followed by any number of dynamically created elements which will all have name attribute values suffixed with the same string (see snippet). I am trying to arrive at an array of jQuery objects, one for each of those input elements.

However, it seems that when I concatenate a 2-element array containing the objects representing the first two elements and a 3-element array containing the objects for the rest of the elements, the result is just an array containing the first array's objects, with just one extra element containing the second array's objects as an array, which is not how I understood concat to work.

I would expect the new array to be a five-element array containing jQuery objects representing the first two fixed inputs, followed by the rest.

Ignoring whether this is the right approach to the problem at hand (it most likely isn't): is my expectation wrong, and can someone explain why concat produces this result?

var firstTwoFields = [
  $('[name=field1]'),
  $('[name=field2]')
];

var otherFields = $('[name$=test]').map(function() { return $(this); });

var newArray = firstTwoFields.concat(otherFields);

document.write('firstTwoFields.length: ' + firstTwoFields.length + '<br>');
document.write('otherFields.length: ' + otherFields.length + '<br>');
document.write('newArray.length: ' + newArray.length + '<br>');
document.write('newArray[2].length: ' + newArray[2].length + '<br>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<input name="field1" value="" /><br>
<input name="field2" value="" /><br>
<input name="field3_test" value="" /><br>
<input name="field4_test" value="" /><br>
<input name="field5_test" value="" /><br>
<br>

Upvotes: 2

Views: 61

Answers (2)

charlietfl
charlietfl

Reputation: 171690

$().map() will return jQuery object that is array like and has a length, but isn't a proper array that you can use Array.prototype methods on.

You need to use get() to return a proper array, or use $.map():

var otherFields = $('[name$=test]').map(function() { return $(this); }).get();

Using $.map():

 var otherFields = $.map( $('[name$=test]'), function(elem) { return $(elem); })

Reference: get() docs

Upvotes: 4

user405398
user405398

Reputation:

Got it. You need to use .get() on otherFields since you use .map() and it returns jQuery object.

var firstTwoFields = [
  $('[name=field1]'),
  $('[name=field2]')
];

var otherFields = $('[name$=test]').map(function() { return $(this); }).get();

var newArray = firstTwoFields.concat(otherFields);

document.write('firstTwoFields.length: ' + firstTwoFields.length + '<br>');
document.write('otherFields.length: ' + otherFields.length + '<br>');
document.write('newArray.length: ' + newArray.length + '<br>');
document.write('newArray[2].length: ' + newArray[2].length + '<br>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<input name="field1" value="" /><br>
<input name="field2" value="" /><br>
<input name="field3_test" value="" /><br>
<input name="field4_test" value="" /><br>
<input name="field5_test" value="" /><br>
<br>

Upvotes: 0

Related Questions