1

I have been using node and redis for some time. The problem I am experiencing is, when I use hgetall in redis, it returns an object.

 { uid: '6203453597',
    first_name: 'Name',
    last_name: 'Surname',
    gender: 'male',
    email: '[email protected]',
    status: '1',
    chips: '4002043' } 

However, when I use hmget and specify the fields I want to get, it returns an array.

[ '6203453597', 'Name', 'Surname', '4002043' ]

So, I would like to convert array to an associative array, just like the first one. What is the best way to convert it from code and performance wise.

I am also using the multi command in redis. So it returns an array of objects in the first example, in the second example it return an array of arrays. So, it is important it to be efficient and automatic, not manual.

YUI's dataschema function is what I am looking for. However it needs to be done on node.js and the only 3rd party utility tool I am using is underscore. Is there any easy way of doing this, or do I need to convert hem in a loop, manually.

Thanks,

4
  • Surely you have no problems to just access the array elements and assign it to object properties. Are you looking for an built-in solution? Commented Feb 13, 2012 at 12:39
  • "So, it is important it to be efficient and automatic, not manual." The only way it can be automatic is if you can get something telling you what array indexes map to what property names. Unless you have a means of querying that, you cannot make it "automatic." Commented Feb 13, 2012 at 12:41
  • @Felix, Yes I don't have any problem doing that however I have an array of arrays. So, it would be better if I could give a schema somehow and apply it. I am looking for an built in (or an easier solution) solution just like YUI's dataschema function, if it exists. Commented Feb 13, 2012 at 12:46
  • @Crowder, yes that's exactly what I want to do actually. I just want to write less code and improve maintainability, instead of doing recursive loops. Since I am using hmget function a lot, it would be good to know a better solution. Commented Feb 13, 2012 at 12:47

3 Answers 3

3

I have built something similar to what you want, but for the sort command. This should work for hmget:

function getFieldsAsObject(key, fields, next) {
    function mapResults(err, values) {
        if(err)
            return next(err);

        var result = {};
        for(var i = 0, len = fields.length; i < len; i++) {
            result[fields[i]] = values[i];
        }
        next(null, result);
    }

    var args = [].concat(key).concat(fields).concat(mapResults);
    client.hmget.apply(client, args);
}

EDIT: A version better suited for your example with multi hmget calls.

// Call with an array of fields and a function(err, results) {}
function mapResults (fields, next) {
    // Return a closure for a multi.exec call
    return function (err, replies) {
        if(err)
            return next(err);

        // Call next with no error and the replies mapped to objects
        next(null, replies.map(mapFields));
    };

    function mapFields (reply) {
        var obj = {};
        for(var i = 0, len = fields.length; i < len; i++)
            obj[fields[i]] = reply[i];
        return obj;
    }
}

Sample usage:

var client = require("redis").createClient()
  , multi = client.multi();

multi.hmget("a.1", "foo", "bar");
multi.hmget("a.2", "foo", "bar");
multi.exec(mapResults(["foo", "bar"], function(err, results) {
    // results will be [{foo: 17, bar: 4711}, {foo: 42, bar: 3.1415926535897932384626433}]
    console.log(results);
}));
Sign up to request clarification or add additional context in comments.

Comments

1

Using Underscore functions pick and values, you can go from 1 to 2

_.values(_.pick({ uid: '6203453597',
    first_name: 'Name',
    last_name: 'Surname',
    gender: 'male',
    email: '[email protected]',
    status: '1',
    chips: '4002043' },"uid","first_name","last_name","chips"))

["6203453597", "Name", "Surname", "4002043"]

or with object you can go from 2 to 1.

_.object(["uid","first_name","last_name","chips"],[ '6203453597', 'Name', 'Surname', '4002043' ])

{uid: "6203453597", first_name: "Name", last_name: "Surname", chips: "4002043"}

Comments

-2

if you want to convert objects to array is simple:

var myarray = new Array();
for(var attrName in myobj){
    myarray.push(myobj[attrName]);
}

1 Comment

Nope, he wants to convert an array to an object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.