How to convert an array to an object in Lodash? - javascript

I have:
{
dis:{["String1","String2","String3"]},
par:"pony"
}
And I want to turn it into this:
[
{ name: 'String1', value: "pony" },
{ name: 'String2', value: "pony" },
{ name: 'String3', value: "pony" }
]

If you change to valid js data you can do this with reduce()
var obj = {
dis: ["String1", "String2", "String3"],
par: "pony"
}
var result = obj.dis.reduce(function(r, e) {
r.push({name: e, value: obj.par});
return r;
}, []);
console.log(result)

You can do it easily, but beware you have double parentheses (mustaches and square bracket).
var
data = {
dis: ["String1","String2","String3"],
par: "pony"
},
result = [];
for (var index in data.dis)
result.push({ name: data.dis[index], value: data.par}
you can find the fiddle here.

You can do it using Array.protoype.map:
var obj = {
dis:["String1","String2","String3"],
par:"pony"
};
var arrOfObj = obj.dis.map(function(name) {
return {
name: name,
value: obj.par
}
});
console.log(arrOfObj)
Or lodash's _.map:
var obj = {
dis:["String1","String2","String3"],
par:"pony"
};
var arrOfObj = _.map(obj.dis, function(name) {
return {
name: name,
value: obj.par
}
});
console.log(arrOfObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>

Related

Create nested object from serializeArray

I'd like to create this structure:
{
"officine_type": "Pharmacie",
"officine_value": 2002626,
"declared_lines": [
{
"ean": 3578835501148,
"qty": 1
},
{
"ean": 3578835502671,
"qty": 2
}
],
"other_value": "my other value"
}
From a serializeArray() with this output:
0: {name: 'declared_lines.0.ean', value: '3578835502244'}
1: {name: 'declared_lines.0.qty', value: '4'}
2: {name: 'declared_lines.1.ean', value: '3578835502220'}
3: {name: 'declared_lines.1.qty', value: '1'}
4: {name: 'declared_lines.2.ean', value: ''}
5: {name: 'declared_lines.2.qty', value: '0'}
6: {name: 'officine_type', value: 'Pharmacy'}
7: {name: 'officine_value', value: '2000461'}
8: {name: 'other_value', value: ''}
I'm struggling on how to push sub-objects in declared_lines
Right now i have this:
let formData = form.serializeArray();
for (let i = 0; i < formData.length; i++) {
if (formData[i]['name'].indexOf('declared_lines') !== 1) {
let inputName = formData[i]['name'].split('.');
let namespace = inputName[0];
let n = inputName[1];
let key = inputName[2];
let subObj = {};
let current = 'declared_lines['+i+']';
let previous = 'declared_lines['+(i-1)+']';
if (obj.hasOwnProperty(namespace) === false) {
obj[namespace] = [];
}
}
obj[formData[i]['name']] = formData[i]['value'];
}
My brain won't go further :(
You could take the name and split it by dot for the path of the new object and the value and build a new object with the given information.
In setValue, the reduce callback checks if the next key is a stringed numerical value and takes an array as default object instead of an object.
function setValue(object, path, value) {
const last = path.pop();
path
.reduce((o, k, i, kk) => o[k] ??= (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {}), object)
[last] = value;
return object;
}
const
data = [{ name: 'declared_lines.0.ean', value: '3578835502244' }, { name: 'declared_lines.0.qty', value: '4' }, { name: 'declared_lines.1.ean', value: '3578835502220' }, { name: 'declared_lines.1.qty', value: '1' }, { name: 'declared_lines.2.ean', value: '' }, { name: 'declared_lines.2.qty', value: '0' }, { name: 'officine_type', value: 'Pharmacy' }, { name: 'officine_value', value: '2000461' }, { name: 'other_value', value: '' }],
result = data.reduce(
(object, { name, value }) => setValue(object, name.split('.'), value),
{}
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Object destructuring and array.reduce can make your code more readable, try:
let formData = [
{name: 'declared_lines.0.ean', value: '3578835502244'},
{name: 'declared_lines.0.qty', value: '4'},
{name: 'declared_lines.1.ean', value: '3578835502220'},
{name: 'declared_lines.1.qty', value: '1'},
{name: 'declared_lines.2.ean', value: ''},
{name: 'declared_lines.2.qty', value: '0'},
{name: 'officine_type', value: 'Pharmacy'},
{name: 'officine_value', value: '2000461'},
{name: 'other_value', value: ''}
];
let output = formData.reduce((acc,cur) => {
let { name, value } = cur;
if(name.indexOf('declared_lines') === -1){
acc[name] = value;
} else {
let [namespace, n, key] = name.split('.');
if(!acc[namespace]) acc[namespace] = [];
if(!acc[namespace][n]) acc[namespace][n] = {};
acc[namespace][n][key] = value;
}
return acc;
}, {});
console.log(output);
In this case reduce starts with an empty object and it loops over your array to process each element (cur).

Json conversion from one form to another

I want to convert this JSON to the format mentioned in the result section.
[
{ name: "FieldData[FirstName][Operator]", value: "=" }
{ name: "FieldData[FirstName][Value]", value: "test" }
{ name: "FieldData[LastName][Operator]", value: "=" }
{ name: "FieldData[LastName][Value]", value: "test" }
]
Result:
FieldData
{
FirstName {
Operator: =,
Value: tset
},
LastName {
Operator: =,
Value: tset
}
}
Using String.prototype.split function and regex, you can extract the strings inside [] and based on that data, you can generate the nested objects as follows.
const input = [
{name: "FieldData[FirstName][Operator]", value: "="},
{name: "FieldData[FirstName][Value]", value: "test"},
{name: "FieldData[LastName][Operator]", value: "="},
{name: "FieldData[LastName][Value]", value: "test"}
];
const result = input.reduce((acc, cur) => {
const keys = cur.name.split(/\[(.*?)\]/).filter((item) => item);
let item = acc;
for (let index = 0; index < keys.length - 1; index ++) {
const key = keys[index];
if (!(key in item)) {
item[key] = {};
}
item = item[key];
}
item[keys[keys.length - 1]] = cur.value;
return acc;
}, {});
console.log(result);
Using a regex and javascript's ability to set properties using obj[propname] = value as the same as obj.propname = value
var d = [
{ name: "FieldData[FirstName][Operator]", value: "=" },
{ name: "FieldData[FirstName][Value]", value: "test" },
{ name: "FieldData[LastName][Operator]", value: "=" },
{ name: "FieldData[LastName][Value]", value: "test" },
];
var r = {};
for (var i=0; i<d.length; ++i)
{
var parts = d[i].name.match(/(.*)\[(.*)\]\[(.*)\]/)
r[parts[1]] = r[parts[1]] || {};
r[parts[1]][parts[2]] = r[parts[1]][parts[2]] || {};
r[parts[1]][parts[2]][parts[3]] = d[i].value;
}
console.log(r)
(note: SO console JSONifies the object, look in the browser console for the object)

Can we assign an object key to another variable like this? [duplicate]

Given a JavaScript object, how can I convert it into an array of objects (each with key, value)?
Example:
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' }
resulting like:
[
{ key: 'firstName', value: 'John' },
{ key: 'lastName', value: 'Doe' },
{ key: 'email', value: 'john.doe#gmail.com' }
]
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' }
var output = Object.entries(data).map(([key, value]) => ({key,value}));
console.log(output);
Inspired By this post
Using map function
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' };
var result = Object.keys(data).map(key => ({ key, value: data[key] }));
console.log(result);
You can just iterate over the object's properties and create a new object for each of them.
var data = { firstName: 'John', lastName: 'Doe', email: 'john.doe#gmail.com' };
var result = [];
for(var key in data)
{
if(data.hasOwnProperty(key))
{
result.push({
key: key,
value: data[key]
});
}
}
The previous answer lead me to think there is a better way...
Object.keys(data).map(function(key) {
return { key, value: data[key] };
});
or in ES6 using arrow functions:
Object.keys(data).map((key) => ({ key, value: data[key] }));
Just make your life easier and use es6 syntax with a map
var output = Object.keys(data).map(key => {
return {
key: key,
value: data[key]
};
})
var result = [];
for(var k in data) result.push({key:k,value:data[k]});
Or go wild and make the key and value keys customizable:
module.exports = function objectToKeyValueArray(obj, keyName = 'key', valueName = 'value') {
return Object
.keys(obj)
.filter(key => Object.hasOwnProperty.call(obj, key))
.map(key => {
const keyValue = {};
keyValue[keyName] = key;
keyValue[valueName] = obj[key];
return keyValue;
});
};
An alternative method for doing this that works on multi level objects and does not use recursion.
var output = []
var o = {
x:0,
y:1,
z:{
x0:{
x1:4,
y1:5,
z1:6
},
y0:2,
z0:[0,1,2],
}
}
var defer = [ [ o ,[ '_root_' ] ] ]
var _defer = []
while(defer.length){
var current = defer.pop()
var root = current[1]
current = current[0]
for(var key in current ){
var path = root.slice()
path.push(key)
switch( current[key].toString() ){
case '[object Object]':
_defer.push( [ current[key] , path ] )
break;;
default:
output.push({
path : path ,
value : current[key]
})
break;;
}
}
if(!defer.length)
defer = _defer.splice(0,_defer.length)
}
[
{ path: [ '_root_', 'x' ], value: 0 },
{ path: [ '_root_', 'y' ], value: 1 },
{ path: [ '_root_', 'z', 'y0' ], value: 2 },
{ path: [ '_root_', 'z', 'z0' ], value: [ 0, 1, 2 ] },
{ path: [ '_root_', 'z', 'x0', 'x1' ], value: 4 },
{ path: [ '_root_', 'z', 'x0', 'y1' ], value: 5 },
{ path: [ '_root_', 'z', 'x0', 'z1' ], value: 6 }
]
const array = [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
];
const obj = Object.fromEntries(array.map(item => [item.key, item.value]));
console.log(obj);
I would say to use npm package flat.
works amazing for nested objects and arrays.
var flatten = require('flat')
flatten({
key1: {
keyA: 'valueI'
},
key2: {
keyB: 'valueII'
},
key3: { a: { b: { c: 2 } } }
})
// {
// 'key1.keyA': 'valueI',
// 'key2.keyB': 'valueII',
// 'key3.a.b.c': 2
// }
const array = [
{ key: "key1", value: "value1" },
{ key: "key2", value: "value2" },
];
const obj = Object.fromEntries(array.map(item => [item.key, item.value]));
console.log(obj);

How to merge 3 javascript object with modified value

I have 3 objects like
[
const arr = [
{name:'ABC', value:123},
{name:'ABC', value:456},
{name:'ABC',value:789},
{name:'DEF',value:9999},
name:'DEF', value:0000}
]
i want output like
updatedArr = [
{name:'ABC', value:123, value1:456, value2:789}
{name:'DEF', value:9999, value1:0000}
]
any kind of links regarding this will be also helpful.
You could use reduce method to create an object and then Object.values to get an array of values.
const arr = [{name:'ABC', value:123},{name:'ABC', value:456},{name:'ABC',value:789},{name:'DEF',value:9999},{name:'DEF', value:0000}]
const res = arr.reduce((r, e) => {
if(!r[e.name]) r[e.name] = {...e}
else {
let {name, ...rest} = r[e.name];
r[e.name][`value${Object.keys(rest).length}`] = e.value
}
return r;
}, {});
console.log(Object.values(res))
const arr = [{
name: 'ABC',
value: 123
},
{
name: 'ABC',
value: 456
},
{
name: 'ABC',
value: 789
},
{
name: 'DEF',
value: 9999
},
{
name: 'DEF',
value: 0000
}
]
const res = Object.values(arr.reduce((acc, item) => {
if (!acc[item.name]) {
acc[item.name] = item;
} else {
acc[item.name]['value' + (Object.keys(acc[item.name]).length - 1)] = item.value;
}
return acc;
}, {}));
console.log(res)
use object assignation:
Object.assign(ob1,ob2);

How to change id to value in object

Have an object that I received from server. in that look
I need to change all "id" to name "value"
Try to parse to JSON change it and convert to the array, but have very bad results
var x = nextProps.campus;
var fff = JSON.stringify(x);
var res = fff.replace(/name/g, "value");
var arr = [];
for (var prop in res) {
arr.push(res[prop]);
}
in result I need like this
var options = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' }
];
You can use Array#map()
var body = [{
id: 1,
name: "school_test_1"
}, {
id: 2,
name: "school_test_2"
}];
var options = body.map((x) => ({value:x.id,label:x.name}));
console.log(options);
You could iterate the array ach assign the new property with the old value and delete the proerty then.
var options = [{ name: 'one', label: 'One' }, { name: 'two', label: 'Two' }];
options.forEach(function (o) {
o.value = o.name;
delete o.name;
});
console.log(options);
You can do that with lodash something like this:
var myData= [{
id: 1,
name: "school_test_1"
}, {
id: 2,
name: "school_test_2"
}]
var changeLabel= {
id: 'value',
name: 'label'
};
var newArray = _.map(myData ,function(obj) {
return _.mapKeys(obj, function(value, key) {
return changeLabel[key];
});
});

Categories