1

Given this JavaScript object:

[
{
    "label": "NewNetworkServiceProvider",
    "value": "NewNetworkServiceProvidered46c4ee-7ec1-45d6-9d13-94e301d2f890"
},
{
    "label": "PurchaseOrderNumber",
    "value": "PurchaseOrderNumber4be9f460-0c98-4038-910d-027565f83e1c"
},
{
    "label": "RawRecordType",
    "value": "RawRecordType2a774afb-0fd4-4fd4-a3c6-88041de5b1ad"
}
]

I would like to modify it to something like this.

{
    "Header": {
        "NewNetworkServiceProvider": "NewNetworkServiceProvidera9ae97fe-e59a-4678-91ea-5a03c7d0f5cc",
        "PurchaseOrderNumber": "PurchaseOrderNumberdf932a47-1476-4a78-a9d0-de538ed8306b",
        "RawRecordType": "RawRecordType12e9d37c-f8dd-4251-bc55-7c83732b5629"
    }
}

So far my code looks like this but I'm unable to use the dynamic label in the final result. Basically, I'd like to replace the 'label' and 'value' dynamically in the new output.

var lscRespDetail = {};
lscRespDetail.data = {};
lscRespDetail.data.results = [];


for (var i = 0; i <= lscheader.data.results.length; i++) {
    if (lscheader.data.results[i] != undefined) {
        var sLabel = lscheader.data.results[i].label;
        var sValue = lscheader.data.results[i].value;

        var obj = {
            Header: {
                sLabel: lscheader.data.results[i].label, sValue: lscheader.data.results[i].value
            }
        };

        obj.sLabel = sLabel;
        obj.sValue = sValue;


        lscResp.data.results.push(obj);

    }

}

3 Answers 3

1

You can use a simple iteration over the array

var obj = {
    header: {}
};
lscheader.data.results.forEach(function (item) {
    obj.header[item.label] = item.value;
});
lscResp.data.results.push(obj);

Demo: Fiddle


To make your code

//need to use the same object in the iteration, should not recreate it in the loop
var obj = {
    header: {}
};
//array index is from 0..length-1
for (var i = 0; i < lscheader.data.results.length; i++) {
    if (lscheader.data.results[i] != undefined) {
        var sLabel = lscheader.data.results[i].label;
        var sValue = lscheader.data.results[i].value;

        //use bracket notation
        obj[sLabel] = sLabel;
    }
}
lscResp.data.results.push(obj);
console.log(obj)

Since you need to have the object key from the value of a variable, you need to use the bracket notation

Sign up to request clarification or add additional context in comments.

1 Comment

lscheader.data.results contains the data. You could update your answer with that
1

A "one-liner" would be

{ Header: 
    input.reduce(function(result, elt) {
        result[elt.label] = elt.value;
        return result;
    }, {})
}

reduce is a common metaphor for constructing an object from an array. We start off with an empty object (the {}), then loop over the elements of the array, adding properties to the object each time through.

If you are in an ES6 environment, the above could be written more compactly using a fat-arrow function:

{ Header: 
    input.reduce((result, elt) => 
        Object.defineProperty(result, elt.label, { value: elt.value }),
    }, {})
}

Merge-based approach

Another approach would be to transform each array element into a little one-property object, and then merge all of those. Assuming I am in an ES6 environment (see below for ES5), that would look like this:

function to_object(elt) { return { [elt.label]: elt.value; } }

The [elt.label] here is an ES6 "computed property name".

Given the input

{
    "label": "NewNetworkServiceProvider",
    "value": "NewNetworkServiceProvidered46c4ee-7ec1-45d6-9d13-94e301d2f890"
}

it returns

{ "NewNetworkServiceProvider": "NewNetworkServiceProvidered46c4ee-..." }

Once I have a way to create these mini-objects, I create an array of them from the original array using map:

input.map(to_object)

This gives me an array of objects, looking like:

[
    { "NewNetworkServiceProvider": "NewNetworkServiceProvidered46c4ee-..." },
    { "PurchaseOrderNumber": "PurchaseOrderNumberdf932a47-1476-4a78-a9d0-de538ed8306b" }
]

Now I need to merge these all together. In ES6, I can do

Object.assign({}, ...input.map(to_object))

using Object.assign and the spread operator.

The final ES6 solution is thus quite compact:

Object.assign({}, ...input.map(elt => ({[elt.label]: elt.value})));

Merging mini-objects if ES5

If you don't have ES6, you could write to_object as

function to_object(elt) { 
    var obj = {};
    obj[elt.label] = elt.value;
    return obj;
}

or

function to_object(elt) {
     return Object.defineProperty({}, elt.label, { value: elt.value });
}

Assuming I have a merge-like function in my library (let's use _.extend; you could also use $.extend), and using apply to accomplish the effect of the spread operator:

_.extend.apply(null, input.map(to_object))

Comments

0

How about mapping the array onto an object?

var obj = {Header: {}};
var header = obj.Header;
lscheader.data.results.map(function (item) {
    header[item.label] = item.value;
});

obj should now hold the structure you want.

3 Comments

You can use forEach instead of map for looping
@vihan1086 6 are one, half a dozen the other. I'd choose map over foreach in this case because OP is technically mapping from one data structure to another.
oh, okay but map also expects an element to be returned. Technically this isn't completely valid and can be confusing to some.

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.