0

If I have object with following structure:

var test = {
     property1: "value1",
     property2: "value2",
     property3: "value3",
     property4: "value4",
     property5: "value5"
}

Assuming that property names are fixed and not always in this order, what is the most elegant way to convert this object into following one:

var test_copy = {
     prop1Copy: "value1",
     propConcat: "value2, value3, value4, value5"
}
Nikola B.
  • 556
  • 2
  • 8
  • 23
  • 1
    How is the name `prop1Copy` generated? And, how do you know what value it gets? Remember, most of the time properties do not have an order to them. – jfriend00 Aug 03 '16 at 21:40
  • prop1Copy is always generated by conactenating values of property2, property3, property4 and property5 in that particular order – Nikola B. Aug 03 '16 at 21:42
  • Properties don't generally have any order to them. I was asking how the actual property name `prop1Copy" is generated? Is that just a hardwired property name? – jfriend00 Aug 03 '16 at 21:46
  • Are all your property names just hardwired to "property1", "property2", etc...? Or are you looking for a generic scheme that takes whatever properties are on an object and creates your copy using whatever properties are there? – jfriend00 Aug 03 '16 at 21:48

4 Answers4

1

I don't think there's any particularly elegant way to do this.

Since your input data has a small number fixed keys there's barely any point using a loop, so this works:

function munge(o) {
    return {
        prop1Copy: o.property1,
        propConcat: [o.property2, o.property3, o.property4, o.property5].join(', ')
    }
}
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Thanks! This was exactly what I was looking for. As long as keys are fixed and there are not to many of them this is the easiest way to concatenate values. – Nikola B. Aug 03 '16 at 21:54
  • 1
    Assuming that you have only 5 properties. – Redu Aug 03 '16 at 21:56
0

Try this:

function concatObject(object, levels){
    var currentLevel = 0;
    var newObj = {propConcat: ""};
    for(var prop in object){
        if(currentLevel < levels){
            newObj[prop] = object[prop];
        }
        else{
            newObj["propConcat"] += object[prop];
        }
    }
}

concatObject(test, 1) would give you the answer, however it would keep the same property name for the variables. You need some kind of function of mapping if you want to change the actual property names (example: from property1 to prop1copy)

This would transform property# to property#copy:

function concatObject(object, levels){
    var currentLevel = 0;
    var newObj = {propConcat: ""};
    for(var prop in object){
        if(currentLevel < levels){
            newObj[prop+"copy"] = object[prop];
        }
        else{
            newObj["propConcat"] += object[prop];
        }
    }
}
David H.
  • 507
  • 2
  • 10
0

Im not sure what you need to accomplish here. But if you want copy first item and concat all other take a look at this.

function concatValues (obj) {
    var resObj = {prop1Copy: ""}, count = 0, mergedArr = [];
    for (var k in obj) {
       count == 0 ? resObj.prop1Copy = obj[k] : mergedArr.push(obj[k]);
       count++;
    }
   resObj.propConcat = mergedArr.join(", ");
   return resObj;
}

Hope this helps

Mykola Borysyuk
  • 3,373
  • 1
  • 18
  • 24
0

Here is a more generic solution that would work on a wider range of input with some caveats.

function concatenateObjectValues(obj) {
    //If you want the output to be sorted differently, you need to provide your own sort order. This sorts by alphabetical order
    var keys = Object.keys(test).sort();

    //assuming the first property would always be the copy
    //removing the first element and returning it
    var copyProp = keys.unshift();

    //generate an array that has the values of the remaining properties from the input
    var concatProp = keys.reduce(function(memo, key) {
        memo.push(test[key]);
        return memo;
    }, []);

    //create `propConcat` and combine the values using the specified separator
    var newObj = {
        propConcat: concatProp.join(", ")
    };

    //add the `prop1Copy` property. The first part of the name would be derived from the actual first property .
    newObj[copyProp + "Copy"] = obj[copyProp];

    return newObj;
}
  • Assuming you want your concatenated properties in alphabetical order, the above would work. If not, then you would need to specify a different sort order. This can be passed in as an argument, if it's going to vary).
  • if the copy property is going to vary, then this code might also need to change. Also, something that can be passed in as a parameter - trivial if it's just the index, but if you have to look them up by name (e.g., if you want to say "prop1" regardless of where it is., you need to also implement that).
  • if the names propConcat and prop1Copy need to vary more than that, the logic needs to be implemented. Or the values passed in...
  • there is no validation. I kept it simple for the sake of the example, but some error handling would be good.

To be honest, if your expected output is going to vary by more than one thing, for example, if you need the copy property to be different and the sort order to be different, then it might just be better to scrap this function. Big variations in the expected input/output make it a bit unwieldy, if you need to pass in most of the stuff to construct the result.

VLAZ
  • 26,331
  • 9
  • 49
  • 67