I am trying to convert an object literal into an array of arrays by using a function.
Using the two sample objects I have, the end result I'm looking for would be:
[ ["ugh","grr"] , ["foo", "bar"] , ["blah" , 138] ] from obj1
[ "shambala","walawala"] , ["foofighter","Barstool"] , ["blahblah",1382342453] ] from obj2
var obj1 = {
ugh: "grr",
foo: "Bar",
blah: 138
};
var obj2 = {
shambala: "walawala",
foofighter: "Barstool",
blahblah: 1382342453
};
var piece1 = Object.keys(obj1);
var piece2 = Object.values(obj1);
var result = [ ];
for (var i = 0; i < piece1.length; i++) {
result.push([piece1[i] , piece2[i]])
}
console.log(result)
From what I have above, I have been able to achieve:
[ ["ugh","grr"] , ["foo", "bar"] , ["blah" , 138] ] from obj1
But I am stumped about how to achieve the same output via a function.
This seems like a simple thing.
function objToArray(objectLiteral) {
var piece1 = Object.keys(objectLiteral);
var piece2 = Object.values(objectLiteral);
var result = [ ];
for (var i = 0; i < piece1.length; i++) {
return result.push([piece1[i] , piece2[i]])
}
}
console.log(objToArray(obj1))
This is what the best I can do but I keep on getting 1 and I don't know why.
Other attempts I just end up with undefined.
The problem with your code is you're using the return earlier than needed, see this working code:
var obj1 = {
ugh: "grr",
foo: "Bar",
blah: 138
};
var obj2 = {
shambala: "walawala",
foofighter: "Barstool",
blahblah: 1382342453
};
function objToArray(objectLiteral) {
var piece1 = Object.keys(objectLiteral);
var piece2 = Object.values(objectLiteral);
var result = [];
for (var i = 0; i < piece1.length; i++) {
result.push([piece1[i], piece2[i]])
}
return result;
}
console.log(objToArray(obj1));
If it's supported in your environment, you could use Object.entries:
var obj1 = {
ugh: "grr",
foo: "Bar",
blah: 138
};
var pairs = Object.entries(obj1);
Alternatively, you could write an entries function like this:
function entries(object) {
const pairs = [];
for(let key in object) {
if(object.hasOwnProperty(key)) {
pairs.push([key, object[key]]);
}
}
return pairs;
}
Here's how I'd implement it.
function objectToArray(obj) {
return Object.keys(obj).map(function(prop) {
return [prop, obj[prop]];
});
}
// ES2015
function objectToArray (obj) {
return Object.keys(obj).map(prop => [prop, obj[prop]]);
}
View demo
Related
I try to create an object with a value for the last key. I just have an Array with the keys and the value but dont know how it will be possible to create an object without use references in javascript.
As far as I know there isnt a way to create a reference of a variable in javascript.
This is what i have:
var value = 'test';
var keys = ['this', 'is', 'a', 'test'];
This is what i want:
myObject: {
this : {
is: {
a : {
test : 'test'
}
}
}
}
Any idea how i can do this the best way in JavaScript ?
How about this...
const value = 'test'
const keys = ['this', 'is', 'a', 'test']
const myObject = keys.reduceRight((p, c) => ({ [c]: p }), value)
console.info(myObject)
Or, if you're not a fan of object literal key shortcuts and arrow functions...
keys.reduceRight(function(p, c) {
var o = {};
o[c] = p;
return o;
}, value);
See Array.prototype.reduceRight() - Polyfill if you need IE <= 8 support.
With this:
var curObj = myObject = {};
for(var i=0; i<keys.length-1; i++)
curObj = curObj[keys[i]] = {};
curObj[value] = keys[i];
Outputs:
{
this : {
is: {
a : {
Test : 'test'
}
}
}
}
As opposed to the other answers, this outputs exactly what you asked for.
Cheers
var o={}, c=o;
var value = 'Test';
var keys = 'this is a test'.split(' ');
for (var i=0; i<keys.length-1; ++i) c = c[keys[i]] = {};
c[keys[i]] = value;
console.log(JSON.stringify(o));
// {"this":{"is":{"a":{"test":"Test"}}}}
If you want the output like
{
this : {
is: {
a : 'test'
}
}
}
Do the following
var keys = ['this', 'is', 'a', 'test'];
var output = keys.reduceRight((p,c)=>({[c]:p}))
console.log(output)
And the output will be like
{ this: { is: { a: 'test' } } }
I have one object that I had to take apart into two arrays to handle properly.
It looked like this:
{
city:"stuttgart",
street:"randomstreet",
...
}
Since it needs to fit a certain directive I had to convert it to:
[
{key:"city", value:"stuttgart"}
{key:"street", value:"randomstreet"},
...
]
for this I first used
var mapFromObjectWithIndex = function (array) {
return $.map(array, function(value, index) {
return [value];
});
};
var mapFromObjectWithValue = function (array) {
return $.map(array, function(value, index) {
return [index];
});
});
to create two arrays, one containing the old key, the other one is holding the old value. Then I created another, two dimensional array map them into a single array doing this
var mapToArray = function (arrayValue, arrayIndex) {
var tableData = [];
for (var i = 0; i<arrayIndex.length; i++){
tableData[i] = {key:arrayIndex[i] , value:arrayValue[i]};
}
return tableData;
};
(maybe I have already messed up by here, can this be done any easier?)
Now, I use the array (tableData) to display the data in a form. The value fields can be edited. In the end, I want to convert the array (tableData) to its original. (see first object)
Please note, that the original object doesn't only contain strings as values, but can also contain objects as well.
I think conversion can be definitely easier:
var obj = {
city:"stuttgart",
street:"randomstreet",
};
var tableData = Object.keys(obj).map(k => {return {key: k, value: obj[k]}});
console.log(tableData);
var dataBack = {};
tableData.forEach(o => dataBack[o.key] = o.value);
console.log(dataBack);
What do you want to do with objects? Do you want to expand them as well? If yes you can do something like this (and it works with nested objects as well):
var obj = {
city:"stuttgart",
street:"randomstreet",
obj: {a: 'a', b: 'b'},
subObject: {aha: {z: 'z', y: 'y'}}
};
function trasformToTableData(obj) {
if (typeof obj !== 'object') return obj;
return Object.keys(obj).map(k => {return {key: k, value: trasformToTableData(obj[k])}});
}
var tableData = trasformToTableData(obj);
console.log(tableData);
function transformBack(obj) {
if (Array.isArray(obj)) {
var support ={};
for (let i = 0; i < obj.length; i++) {
support[obj[i].key] = transformBack(obj[i].value)
}
return support;
}
return obj;
}
var dataBack = {};
tableData.forEach(o => dataBack[o.key] = transformBack(o.value));
console.log(dataBack);
Let's have some fun and turn our object into iterable to do the job as follows;
var input = {city:"stuttgart", street:"randomstreet", number: "42"};
output = [];
input[Symbol.iterator] = function*(){
var ok = Object.keys(this),
i = 0;
while (i < ok.length) yield {key : ok[i], value: this[ok[i++]]};
};
output = [...input];
console.log(output);
This function will map your object to an array when you call objVar.mapToArray(), by using Object.keys() and .map()
Object.prototype.mapToArray = function() {
return Object.keys(this).map(function(v) {
return { key: v, value: this[v] };
}.bind(this));
}
I would do something like this:
var dataObj = {
city:"stuttgart",
street:"randomstreet",
};
function toKeyValue(obj) {
var arr = [];
for (var key in obj) {
if(obj.hasOwnProperty(key)) {
arr.push({'key': key, 'value': obj[key]});
}
}
return arr;
}
var arrayKeyValue = toKeyValue(dataObj);
console.log(arrayKeyValue);
I have an array of objects like this:
[
{ "key": "fruit", "value": "apple" },
{ "key": "color", "value": "red" },
{ "key": "location", "value": "garden" }
]
I need to convert it to the following format:
[
{ "fruit": "apple" },
{ "color": "red" },
{ "location": "garden" }
]
How can this be done using JavaScript?
You can use .map
var data = [
{"key":"fruit","value":"apple"},
{"key":"color","value":"red"},
{"key":"location","value":"garden"}
];
var result = data.map(function (e) {
var element = {};
element[e.key] = e.value;
return element;
});
console.log(result);
also if you use ES2015 you can do it like this
var result = data.map((e) => {
return {[e.key]: e.value};
});
Example
Using an arrow function, with the data called arr
arr.map(e => {
var o = {};
o[e.key] = e.value;
return o;
});
This generates a new Array and does not modify the original
It can be simplified down to one line as
arr.map(e => ({[e.key]: e.value}));
If you can't assume arrow function support yet, you would write this longhand
arr.map(function (e) {
var o = {};
o[e.key] = e.value;
return o;
});
Using map (as suggested in other answers) or the following will do what you want...
var data = [{"key":"fruit","value":"apple"},{"key":"color","value":"red"},{"key":"location","value":"garden"}];
var obj = {};
for(var i = 0; i < data.length; i++) {
obj[data[i]["key"]] = data[i]["value"];
}
In Javascript, obj.property and obj['property'] return same things.
obj['property'] is more flexible because the key 'property' could be a string with some space :
obj['pro per ty'] // work
obj.pro per ty // not work
or
var a = 'property';
obj.a == obj.property // => false
obj[a] == obj.property // => true
So you could try that.
var data = [{"key":"fruit","value":"apple"},{"key":"color","value":"red"},{"key":"location","value":"garden"}]
var new_data = [];
var data_length = data.length; // just a little optimisation for-loop
for (var i = 0; i < data_length; i++) {
var item = data[i]; // to have a vision close of foreach-loop (foreach item of collection)
new_data[i] = {};
new_data[i][item.key] = item.value;
}
console.log(new_data);
// [{"fruit":"apple"},{"color":"red"},{"location":"garden"}]
What you currently have is an array of object, each having two attributes, key and value. If you are not aware of map, you can always run a forEach loop on this array and rearrange the data. Try something like below:
function() {
var newArray = [];
oldArray.forEach(function(x){
var obj= {};
obj[x.key] = x.value;
newArray.push(obj);
});
console.log(newArray);
}
here oldArray is your original data
I have this array:
["userconfig", "general", "name"]
and I would like it to look like this
data_structure["userconfig"]["general"]["name"]
I have tried this function:
inputID = "userconfig-general-name"
function GetDataByID(inputID){
var position = '';
for (var i = 0; i < inputID.length; i++) {
var hirarchy = inputID[i].split('-');
for (var index = 0; index < hirarchy.length; index++) {
position += '["'+ hirarchy[index] +'"]';
}
}
return data_structure[position];
}
while hirarchy is the array. I get the [position] as a string which is not working well.
how can I make a js function which builds the object path dynamically by an array?
var arr = ["userconfig", "general", "name"];
var dataStructure = arr.reduceRight(function (value, key) {
var obj = {};
obj[key] = value;
return obj;
}, 'myVal');
Ends up as:
{ userconfig : { general : { name : 'myVal' } } }
Note that you may need a polyfill for the reduceRight method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
The below function will take an object to modify and an array filled with the properties needed:
function objPath(obj,path){
path.forEach(function(item){
obj[item] = {};
obj = obj[item];
});
}
var myobj = {};
objPath(myobj,["test","test2","test3"]);
console.log(myobj);
//outputs
Object {test: Object}
test: Object
test2: Object
test3: Object
The function loops over the array creating the new object property as a new object. It then puts a reference to the new object into obj so that the next property on the new object can be made.
JSFiddle
Recursive function
var array = ["userconfig", "general", "name"];
function toAssociative(array) {
var index = array.shift();
var next = null;
if (array.length > 0) {
next = toAssociative(array);
}
var result = new Array();
result[index] = next;
return result;
}
How can I reach into a object using an array and set a value - preferably without using eval, doing something like object[eval(["key", "deepkey"].split("")) = "newvalue"?
Doing it manually, I would just do object.key.deepkey = "newvalue", but again, I need to do this using an array to reach into the right property.
The object for reference:
object = {
key: {
deepKey: "value"
}
}
You can use a recursive function to step through each level of the array (or object) like so:
function val(array, indices) {
if(indices.length > 1) {
var idx = indices.shift();
return val(array[idx], indices);
}
else {
return array[indices.shift()];
}
}
var obj = { a: { b: 'c' } };
//result is 'c'
var result = val(obj, ['a', 'b']);
If you want to get an object reference, simply specify the second arg only up to that:
var obj = {
a: {
b: {
c: 'foo'
}
}
};
var ref = val(obj, ['a', 'b']);
//ref is now obj.a.b, so you can do something like...
ref.x = 'bar';
console.dir(ref); //outputs something like { c: 'foo', x: 'bar' }
You can write array type syntax as. jsfiddle
object = {
key: {
deepKey: "value"
}
}
object['key']['deepkey']='newvalue'
if you have keys in array you can do this
var keys = ['key','deepkey'];
var obj = object;
for(var k =0; k <keys.length-1; k++){
obj= obj[keys[k]];
}
obj[keys[k]] = 'newvalue'
You can take the function from this question and rework it to access properties of an object.
http://jsfiddle.net/jbabey/Mu4rP/
var getPropByName = function (propName, context) {
var namespaces = propName.split('.');
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context;
};
var myObject = {
someKey: {
deepKey: "value"
}
};
myObject.someKey.deepKey; // "value"
getPropByName('someKey.deepKey', myObject); "value"
An alternative could be using Array.map this way:
function deepkey(obj,keys,set){
var i=1
,kys = keys.split('.')
,exist = kys.map( function(k){
var prev = this[i-1], isobj = prev.constructor === Object;
this.push( isobj && k in prev ? prev[k] : prev);
return (i++,this[i-1]);},
[obj]
)
,x = exist[exist.length-2];
if (x && x.constructor === Object && set){
x[kys[kys.length-1]] = set;
}
return x[kys.pop()] || null;
}
// usage
var obj = { a:{ b:{ c:1, cc:{ d:{ e:{ a:1,b:2,c:3 } } } } } };
// assign [1,2,3,4,5] to obj.a.b.cc.d.e.b
console.log(deepkey(obj,'a.b.cc.d.e.b',[1,2,3,4,5])); //=> [1,2,3,4,5]
// get obj.a.b.cc.d.e.b[2]
console.log(deepkey(obj,'a.b.cc.d.e.b')[2]); //=> 3
// get non existing path obj.a.b.c.d.e.b
console.log(deepkey(obj,'a.b.c.d.e.b')); //=> null