Reputation: 1592
How can I use a dictionary of text names and values to set properties on an object? For example...
I need to populate this object:
item = {};
Using this collection of values (note everything is a string):
values = [
{ id: 1, name: "a", value: "true" },
{ id: 2, name: "b", value: "false" },
{ id: 3, name: "c", value: "100" },
{ id: 4, name: "d", value: "[email protected]" }
];
So that the original object looks like this:
item = {
a: true,
b: false,
c: 100,
d: '[email protected]'
}
Sorry for being so vague, but I'm not sure where to even start.
Upvotes: 3
Views: 6564
Reputation:
In ES6:
Object.assign({}, ...values.map(value => ({[value.name]: value.value})))
This creates an array of little objects each with one key-value pair, using ES6's computed property names, then uses the spread operator (...
) to pass them to Object.assign
as parameters to be merged.
To transform the values, such as converting "true"
to true
, change value.value
to transform(value.value)
and write the transform
function:
function transform(value) {
return value === "true" ? true :
value === "false" ? false :
!isNaN(value) ? +value :
value;
}
Upvotes: 0
Reputation: 41075
You can use reduce (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) to reduce the array (in)to a single object
values.reduce(function(a, b){
a[b.name] = b.value;
return a ;
}, item)
Stack Snippet
var values = [
{ id: 1, name: "a", value: "true" },
{ id: 2, name: "b", value: "false" },
{ id: 3, name: "c", value: "100" },
{ id: 4, name: "d", value: "[email protected]" }
];
var item = {};
so.log(values.reduce(function(a, b){ a[b.name] = b.value; return a }, item));
body {
font-family: verdana;
font-size: 10px;
}
<div id="a"></div>
<script>
var so = {
log: function(e) {
document.getElementById("a").innerText = JSON.stringify(e, null, ' ');
}
}
</script>
And if you also want to cast the string to the appropriate type, here is a rudimentary way of doing it
values
// convert the properties - note that this CHANGES the values array
// if you don't want to do that precede this by a .slice() - creates a copy of values
.map(function (e) {
// check if the string is true of false
if (e.value === "true" || e.value === "false")
e.value = (e.value === "true");
// check if number
else if (!isNaN(e.value))
e.value = Number(e.value);
return e;
})
.reduce(function (a, b) {
a[b.name] = b.value;
return a;
}, item)
Stack Snippet
var values = [
{ id: 1, name: "a", value: "true" },
{ id: 2, name: "b", value: "false" },
{ id: 3, name: "c", value: "100" },
{ id: 4, name: "d", value: "[email protected]" }
];
var item = {};
so.log(values
.map(function (e) {
if (e.value === "true" || e.value === "false")
e.value = (e.value === "true");
else if (!isNaN(e.value))
e.value = Number(e.value);
return e;
})
.reduce(function (a, b) {
a[b.name] = b.value;
return a;
}, item));
body {
font-family: verdana;
font-size: 10px;
}
<div id="a"></div>
<script>
var so = {
log: function(e) {
document.getElementById("a").innerText = JSON.stringify(e, null, ' ');
}
}
</script>
Upvotes: 2
Reputation: 239240
You need to iterate over values
, using the value of the name
property of each item in that array as a key, and the value of the value
property as the value:
var item = {}
values.forEach(function(i) {
item[i.name] = i.value
})
Upvotes: 4