Tedderz
Tedderz

Reputation: 587

Joining Together Javascript Object Members?

Given any object with members that look like this:

target
{
    x1 : 1
    x2 : 2
    x3 : 3
    y1 : 6
    y2 : 5
    y3 : 4
}

I need to transform the object into something like this:

target
{
    x : [1, 2, 3]
    y : [6, 5, 4]
}

From the basic JavaScript I know, it seems like the following function would work:

function joinParameters(target, paramName) {
    var count = 1;
    var array = [];
    var name = paramName.concat(count);
    var value = target[name];
    while (typeof value != undefined) {
        array.push(value);
        name = paramName.concat(count);
    }
    target[paramName] = array;
}

So, I could say joinParameters(target, "x"); The problem, however, is that

    var value = target[name];

is always undefined. I followed the code in FireBug to make sure that the target object has the property that I'm trying to get, and it does. So, I'm not quite sure what's wrong.

If jQuery has an elegant way of doing this, then I would prefer that solution.

Upvotes: 3

Views: 1423

Answers (4)

zachallia
zachallia

Reputation: 1495

you could do:

function joinParams(o) { 
    var ret = {},
        key;
    for(var i in o) {
        key = i.substr(0,1);
        ret[key] = ret[key] ? ret[key].push(o[i]) && ret[key] : [o[i]];
    } 
    return ret;
}


var target = /* original object */
target = joinParams(target);

Upvotes: 2

moey
moey

Reputation: 10897

There are some logic errors in your original code (i.e. infinite loop). Fix:

function joinParameters(target, paramName) {
    var count = 1;
    var array = [];
    var name = paramName.concat(count);
    var value = target[name];
    while (value != undefined) {   /* typeof value will return "undefined". */
        array.push(value);
        /* You need to increment 'count'. */
        name = paramName.concat(++count);
        value = target[name];
    }
    target[paramName] = array;
}

...

joinParameters(target, "x");

Note this function call will add a new element x to target, x1, x2, ..., x6 will still exist in target. In fact, this function doesn't take care of the y element, which I assume you want to "join" as well.

For a more versatile function, the answer by zachallia should do the trick.

Upvotes: 1

david
david

Reputation: 18288

Using underscore.js:

_(target).keys().reduce(function(memo, key){
    var split = /([^\d]+)([\d]+)/.exec(key);
    memo[split[1]] = memo[split[1]]||[];
    memo[split[1]][parseInt(split[2],10)-1] = target[key];
    return memo;
},{});

Working example:

http://jsfiddle.net/PLgN5/

Upvotes: 3

amit_g
amit_g

Reputation: 31260

function joinParams(target) {
    var p;

    for (prop in target) {
        p = prop.substr(0, 1);

        if (!target[p]) {
                target[p] = [];
        }

        target[p].push(target[prop]);
    }

    return target;
}

target =
{
    x1 : 1,
    x2 : 2,
    x3 : 3,
    y1 : 6,
    y2 : 5,
    y3 : 4
}

target = joinParams(target);

Upvotes: 3

Related Questions