Zachary Scott
Zachary Scott

Reputation: 21172

JQuery $.extend doesn't work like I would expect: How to code this correctly?

Here is the JQuery extend page.

What I would expect this to do is take two arrays, join them together and create uniform properties for each resulting array element. How do I get this to work as expected?

var a = [];
a.push({ "id": 1, "text": "one" });
a.push({ "id": 2, "text": "two" });
a.push({ "id": 3, "text": "three" });
var b = [];
b.push({"id":3 , "selected":true});
var c = [];
$.extend(c,a,b);

What I would expect is that the resulting array would include:

{ "id": 1, "text": "one", "selected": false }
{ "id": 2, "text": "two", "selected": false }
{ "id": 3, "text": "three", "selected": true }

but instead it seems to just copy the first array over top of the second:

{ "id": 3, "text": null, "selected": true }
{ "id": 2, "text": "two" }
{ "id": 3, "text": "three" }

The documentation includes:

When we supply two or more objects to $.extend(), properties from all of the objects are added to the target object.

What am I doing wrong, or how would I accomplish this otherwise?

EDIT: Jball's suggestion implemented:

var a = [];
a.push({ "id": 1, "text": "one" });
a.push({ "id": 2, "text": "two" });
a.push({ "id": 3, "text": "three" });
var b = [];
b.push({ "id": 3, "selected": true });
var c = [];
for (var index = 0; index < a.length; index++) {
   var tempresult = {};
   var tempb = b.filter(
      function (ele, idx, collection) {
         return (collection[idx].id == index + 1);
      });
   if (tempb.length == 0)
      tempb = [{ "id": index + 1, "selected": false }];
   $.extend(tempresult, a[index], tempb[0]);
   c.push(tempresult);
} 

produces:

[{"id":1, "selected":false, "text": "one"},
 {"id":2, "selected":false, "text": "two"},
 {"id":3, "selected":true,  "text": "three"}]

That's the answer. Now I wonder if it can be cleaned up a bit.

Upvotes: 1

Views: 1301

Answers (1)

jball
jball

Reputation: 25014

I'm not sure if you noticed it, but the $.extend() function is intended for properties of objects, not elements of an array.

It seems like you need to create a function to loop through the arrays, and call $.extend() on matching elements to get your desired result. You would have to decide whether you want to add or ignore non-matching elements from the second array.

The problem is that jQuery has no idea what elements in your array are matching, and so matches them by index, though I'm not sure why the result for the first item has "text": "three" instead of "text": "one", unless it is attempting to match by the individual items properties after it does an $.extend() based on index.

Upvotes: 1

Related Questions