Convert array of objects to object using lodash - javascript

I have an array of objects that i need to convert to a single object.
ex:need to convert
var data=[
{
"name": "EMPRESA",
"value": "CMIP"
},
{
"name": "DSP_DIRECAO",
"value": "CMIP#040#1900-01-01"
},
{
"name": "DSP_DEPT",
"value": "CMIP#040#1900-01-01#42#1900-01-01"
},
...
]
to
{
"EMPRESA": "CLCA",
"DSP_DIRECAO": "CLCA#100#1900-01-01",
"DSP_DEPT": "CLCA#100#1900-01-01#100#1900-01-01",
...
}
Turn data[x][name] to propertie and data[x][value] to atribute value
Thanks

Doesn't use LoDash, but a straight forward reduce()
var obj = data.reduce( (a,b) => {
return a[b.name] = b.value, a;
}, {});
var data=[
{
"name": "EMPRESA",
"value": "CMIP"
},
{
"name": "DSP_DIRECAO",
"value": "CMIP#040#1900-01-01"
},
{
"name": "DSP_DEPT",
"value": "CMIP#040#1900-01-01#42#1900-01-01"
}
]
var obj = data.reduce( (a,b) => {
return a[b.name] = b.value, a;
}, {});
console.log(obj);
Doing the same in LoDash would be something like
var obj = _.transform(data, (a,b) => {
return a[b.name] = b.value, a;
},{});

On lodash 4.15,
_.chain(data).keyBy("name").mapValues("value").value()
On lodash 3.10,
_.chain(data).indexBy("name").mapValues("value").value()

var newObj = {}
var data = [{
"name": "EMPRESA",
"value": "CMIP"
}, {
"name": "DSP_DIRECAO",
"value": "CMIP#040#1900-01-01"
}, {
"name": "DSP_DEPT",
"value": "CMIP#040#1900-01-01#42#1900-01-01"
}]
data.forEach(function(d) {
newObj[d.name] = d.value
})

Related

Return additional properties using reduce and spread operator JS?

I am using the reduce function below to count how many times a players name is mentioned and then list them based on who was mentioned the most to the least.
I am trying to return the 2nd property [`${value.subtitles[0].name} + ${index}`] : value.subtitles[0].url with my object and sort it. However it is not sorting properly. When only returning the first property [value.title]: (acc[value.title] || 0) + 1, everything works as intended. But the second property is making it sort incorrectly. It is supposed to be sorting based on the title property value which is an integer of how many times that player was mentioned, from most to least. Why is this happening?
Thanks for the help!
const players = [
{
"title": "Mike",
"titleUrl": "https://mikegameplay",
"subtitles": [
{
"name": "Mike Channel",
"url": "https://channel/mike"
}
]
},
{
"title": "Cindy",
"titleUrl": "https://cindy",
"subtitles": [
{
"name": "Cindy Channel",
"url": "https://channel/cindy"
}
]
},
{
"title": "Mike",
"titleUrl": "https://mike",
"subtitles": [
{
"name": "Mike Channel",
"url": "https://channel/mike"
}
]
},
{
"title": "Haley",
"titleUrl": "https://Haley",
"subtitles": [
{
"name": "Haley Channel",
"url": "https://channel/haley"
}
]
},
{
"title": "Haley",
"titleUrl": "https://Haley",
"subtitles": [
{
"name": "Haley Channel",
"url": "https://channel/haley"
}
]
},
{
"title": "Haley",
"titleUrl": "https://Haley",
"subtitles": [
{
"name": "Haley Channel",
"url": "https://channel/haley"
}
]
}
]
const counts = players.reduce((acc, value, index) => ({
...acc,
[value.title]: (acc[value.title] || 0) + 1,
[`${value.subtitles[0].name} + ${index}`] : value.subtitles[0].url
}), {});
const sortedValues = [];
for (const value in counts) {
sortedValues.push([value, counts[value]]);
};
sortedValues.sort((a, b) => b[1] - a[1]);
console.log(sortedValues)
try this
var groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
var pl = groupBy(players, "title");
console.log(pl);
let sortable = [];
for (var item in pl) {
sortable.push([item, pl[item].length, pl[item][0].subtitles[0].url]);
}
sortable.sort(function (a, b) {
return b[1] - a[1];
});
console.log(JSON.stringify(sortable));
result
[["Haley",3,"https://channel/haley"],["Mike",2,"https://channel/mike"],["Cindy",1,"https://channel/cindy"]]

How in JS to merge in one object two json objects where the ID of on object correspond on the same ID of the second object

My question relates to the fact I'm querying 2 different objects from DB and the result is in JSON. I need to merge them into one.
The 2 objects have in common this two key/value IRBId = ... and id = ... and they look as an example
OBJ 1
{
"data":{
"IRBs":{
"nodes":[
{
"id":"8",
"name":"Admin ",
},
{
"id":"9",
"name":"Again",
}
],
}
}
}
OBJ 2
{
"data":{
"informedConsentForms":{
"count":3,
"nodes":[
{
"id":"93",
...
"IRBId":"9",
},
{
"id":"92",
...
"IRBId":"8",
},
{
"id":"91",
...
"IRBId":"8",
}
],
}
},
As you will see above OBJ 2 and OBJ 1 corresponding with the same at IRBid and id.
What I need is to merge the two OBJ where IRBId OBJ 2 === id OBJ 1
The result I would expect after the merge is
OBJ merged
{
[{
"id":"93",
...
"IRBId":"9",
"irb": {
"name":"Again ",
...
}
},
{
"id":"92",
...
"IRBId":"8",
"irb": {
"name":"Admin ",
...
}
},
{
"id":"91",
...
"IRBId":"8",
"irb": {
"name":"Admin ",
...
}
],
},
I don't know how to make it looks like this.
Try using Array.reduce
Logic
Loop through second object data nodes
Find the matching nodes from object 1 data nodes.
Push to accumulator with required details. (I have added only the nodes that was mentioned in in Expected resut, you can add asmuch as you need.)
const obj1 = {
"data": {
"IRBs": {
"nodes": [
{
"id": "8",
"name": "Admin ",
},
{
"id": "9",
"name": "Again",
}
],
}
}
}
const obj2 = {
"data": {
"informedConsentForms": {
"count": 3,
"nodes": [
{
"id": "93",
"IRBId": "9",
},
{
"id": "92",
"IRBId": "8",
},
{
"id": "91",
"IRBId": "8",
}
],
}
},
};
const obj1List = obj1.data.IRBs.nodes;
const output = obj2.data.informedConsentForms.nodes.reduce((acc, curr) => {
const matchingNode = obj1List.find((item) => item.id === curr.IRBId);
if (matchingNode) {
acc.push({
id: curr.id,
IRBId: curr.IRBId,
irb: {
name: matchingNode.name
}
})
}
return acc;
}, []);
console.log(output);
You need to use the map function on the nodes in the first object to construct a new object that contains the second and first object's attributes.
const obj1 = {
"data": {
"IRBs": {
"nodes": [{
"id": "8",
"obj1": "one",
"name": "Admin ",
},
{
"id": "9",
"obj1": "two",
"name": "Again",
}
]
}
}
};
const obj2 = {
"data": {
"informedConsentForms": {
"count": 3,
"nodes": [{
"id": "93",
"obj2": "1",
"IRBId": "9",
},
{
"id": "92",
"obj2": "2",
"IRBId": "8",
},
{
"id": "91",
"obj2": "3",
"IRBId": "8",
}
],
}
}
};
const obj1Data = obj1.data.IRBs.nodes;
const obj2Data = obj2.data.informedConsentForms.nodes;
const res = obj2Data.map(item => {
const obj1Item = obj1Data.find(obj1Item => item.IRBId === obj1Item.id);
return obj1Item ? { ...item, "irb": { ...obj1Item}} : { ...item};
});
console.log(res);
i am using nested loop, try this one
const obj2 = {
"data":{
"informedConsentForms":{
"count":3,
"nodes":[
{
"id":"93",
"IRBId":"9",
},
{
"id":"92",
"IRBId":"8",
},
{
"id":"91",
"IRBId":"8",
}
],
}
},
}
const obj1 = {
"data":{
"IRBs":{
"nodes":[
{
"id":"8",
"name":"Admin ",
},
{
"id":"9",
"name":"Again",
}
],
}
}
}
const result = [];
const obj2Nodes = obj2.data.informedConsentForms.nodes;
for(let i = 0; i < obj2Nodes.length; i++) {
const obj1Nodes = obj1.data.IRBs.nodes
for(let j = 0; j < obj1Nodes.length; j++) {
if(obj2Nodes[i].IRBId === obj1Nodes[j].id) {
const {id, ...reObj1Nodes} = obj1Nodes[j];
result.push({
...obj2Nodes[i],
'irb': {
...reObj1Nodes
}
})
}
}
}
console.log(result)

Lodash compare/merge object to array

I need to compare/merge 2 objects with diferent structure using Lodash.
data= [
{
"name": "EMPRESA",
"value": ""
},
{
"name": "DESIGEMPRESA",
"value": "CMIP"
},
{
"name": "UTILIZADOR",
"value": ""
},
{
"name": "CD_INDICADOR",
"value": ""
},
{
"name": "DT_INI_INDICADOR",
"value": ""
},
{
"name": "DT_INI",
"value": "2017-12-13"
},
.....
]
and
dbcolsData={
"EMPRESA": "",
"UTILIZADOR": "paulo.figueiredo",
"CD_INDICADOR": "",
"DT_INI_INDICADOR": "",
"DT_INI": "",
"DT_FIM": ""
}
The question is how i can fill the values of data with the values of dbcolsData ?
Lets say put the values of dbColsData in data
Thanks in advance
Try something like this:
_.forEach(data, function(object){
object.value = dbcolsData[object.name];
})
Use Array#map (or lodash's _.map()) to iterate the data, and get the results from dbcolsData:
var data = [{"name":"EMPRESA","value":""},{"name":"DESIGEMPRESA","value":"CMIP"},{"name":"UTILIZADOR","value":""},{"name":"CD_INDICADOR","value":""},{"name":"DT_INI_INDICADOR","value":""},{"name":"DT_INI","value":"2017-12-13"}];
var dbcolsData = {"EMPRESA":"","UTILIZADOR":"paulo.figueiredo","CD_INDICADOR":"","DT_INI_INDICADOR":"","DT_INI":"","DT_FIM":""};
var result = data.map(function(o) {
return Object.assign({ data: dbcolsData[o.name] }, o);
});
console.log(result);
Reduce data to the dbcolsData structure :
var myData = data.reduce((o, nvO) => Object.defineProperty(o, nvO.name, {value: nvO.value}), {})
->
Now you can use lodash comparison functions like _.isEqual :
_.isEqual(myData, dbcolsData)

Javascript underscore data format array of object

By using underscoreJS lib and manipulating some datas, i have this object
var data = {
"2017-09-26": [
{
"id": 274281,
"value": 10
},
{
"id": 274282,
"value": 20
}],
"2017-09-27": [
{
"id": 274281,
"value": 12
},
{
"id": 274282,
"value": 13
}],
}
i would like to obtain this result below by passing the keys as date in the child object and transform the value of id key as the new key of the value of value
var data = [{
date:"2017-09-26",
274281: 10,
274282: 20
},
{
date:"2017-09-27",
274281: 12,
274282: 13
}]
Please does someone as an idea to help me to do this and ideally efficiently?
Thanks
Here it is in one line:
Object.keys(data).map(key => ({date: key, ...data[key].reduce((p, c) => {p[c.id] = c.value; return p}, {})}))
Result:
[{
"274281":10,
"274282":20,
"date":"2017-09-26"
},
{
"274281":12,
"274282":13,
"date":"2017-09-27"
}]
You need nested loops. The first level creates the objects with the date property, then you loop over the objects in that value, and add the id: value properties to the result.
var newdata = _.map(data, (date, objects) => {
res = {date: date};
_.each(objects, obj => {
res[obj.id] = obj.value;
});
return res;
});
You can use Array.from() on the result of Object.entries(data) to create an array of objects by passing a callback function as the second argument.
Then for each sub-array, use .reduce() to create a new object from its members.
var data = {
"2017-09-26": [
{ "id": 274281, "value": 10 },
{ "id": 274282, "value": 20 }
],
"2017-09-27": [
{ "id": 274281, "value": 12 },
{ "id": 274282, "value": 13 }
],
};
const result = Array.from(Object.entries(data), ([key, arr]) =>
arr.reduce((res, {id, value}) =>
Object.assign(res, {[id]: value})
, {date: key})
);
console.log(result);
Here's one that's just about the same, but uses the new object literal spread syntax.
var data = {
"2017-09-26": [
{ "id": 274281, "value": 10 },
{ "id": 274282, "value": 20 }
],
"2017-09-27": [
{ "id": 274281, "value": 12 },
{ "id": 274282, "value": 13 }
],
};
const result = Array.from(Object.entries(data), ([key, arr]) =>
({date: key,
...Object.assign({}, ...arr.map(({id, value}) => ({[id]: value})))
})
);
console.log(result);

How to combine multiple key values in JSON object?

I have this sample JSON object
var sample = [{
"label": "one",
"value": 1
}, {
"label": "two",
"value": 2
}, {
"label": "three",
"value": 3
}, {
"label": "four",
"value": 4
}, {
"label": "five",
"value": 5
}];
I want to change it some thing like this
var sample = [{
"label": "one",
"value": 1,
"newKeyValue": "one|1"
}, {
"label": "two",
"value": 2,
"newKeyValue": "two|2"
}, {
"label": "three",
"value": 3,
"newKeyValue": "three|3"
},
...
];
It should combine both key values and return new key value combining both.
JSON is coming dynamically key label and value are not static it can be anything. For example [{"name":"srinivas","lastname":"pai"}]
You can use map like this :
EDIT
For handling generic keys you can use
Object.keys(d)[0] for first key
Object.keys(d)[1] for second key
var sample = [
{
"label":"one",
"value":1
},
{
"label":"two",
"value":2
},
{
"label":"three",
"value":3
},
{
"label":"four",
"value":4
},
{
"label":"five",
"value":5
}
];
var data = sample.map(function(d){
return {label: Object.keys(d)[0], value: Object.keys(d)[1], newKeyValue: Object.keys(d)[0] +"|" + Object.keys(d)[1]}
})
console.log(data)
Hope this helps!
You can use Array#map(), Object.keys(), and Array#join().
In ES6, you can use Arrow functions.
sample = sample.map(obj => {
var keys = Object.keys(obj);
obj.newKeyValue = keys.map(key => obj[key]).join('|');
return obj;
});
var sample = [{
"label": "one",
"value": 1
}, {
"name": "two",
"age": 2
}, {
"five": "three",
"six": 3
}, {
"company": "four",
"organization": 4
}, {
"label": "five",
"value": 5
}];
sample = sample.map(function (x) {
var keys = Object.keys(x);
x.newKeyValue = keys.map(key => x[key]).join('|');
return x;
});
console.log(sample);
document.body.innerHTML = '<pre>' + JSON.stringify(sample, 0, 4) + '</pre>';
In ES5, you can use the same code with anonymous functions
sample = sample.map(function (obj) {
var keys = Object.keys(obj);
obj.newKeyValue = keys.map(function (key) {
return obj[key]
}).join('|');
return obj;
});
Limitations due to dynamic keys:
The order of the keys in object cannot be maintained
This will join all the available keys in the object (in case if you just want to join fewer)
var sample = [
{
"label":"one",
"value":1
},
{
"label":"two",
"value":2,
"optionalValue":2
},
{
"label":"three",
"value":3,
"remarks":"free text"
},
{
"label":"four",
"value":4
},
{
"label":"five",
"value":5
}
];
for (var key in sample) {
var newValue = [];
for (var piece in sample[key]){
newValue.push(sample[key][piece])
}
sample[key]["newKeyValue"] = newValue.join('|');
}
$('pre').html(JSON.stringify(sample,null,4));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>
You can use Array.prototype.forEach() for in situ changes.
The forEach() method executes a provided function once per array element.
Edit: with dynamic keys, stored in an array, because of the order.
var sample = [{ "label": "one", "value": 1 }, { "label": "two", "value": 2 }, { "label": "three", "value": 3 }, { "label": "four", "value": 4 }, { "label": "five", "value": 5 }];
sample.forEach(function (a) {
a.newKeyValue = ['label', 'value'].map(function (k) { return a[k]; }).join('|');
});
document.write('<pre>' + JSON.stringify(sample, 0, 4) + '</pre>');
If more element are their then use $.extend
var sample = [
{
"label":"one",
"value":1
},
{
"label":"two",
"value":2
},
{
"label":"three",
"value":3
},
{
"label":"four",
"value":4
},
{
"label":"five",
"value":5
}
];
$(sample).each(function(i,item){
var keyes = Object.keys(item);
sample[i] = $.extend(item,{newKeyValue: item[keyes[0]] +"|" +item[keyes[1]]});
});
console.log(sample)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
$.extend also helpful when you are having more objects already and you want to merge both
eg.
var base = {
"label":"one",
"value":1
}
and you want to add more objects
var extra = {
"new1":"value1",
"new2":"value2",
"new3":"value3",
"new4":"value4",
}
then it will be done by
$.extend(base,extra);
Output:
{
"label":"one",
"value":1,
"new1":"value1",
"new2":"value2",
"new3":"value3",
"new4":"value4",
}
var sample = [{"name":"srinivas","lastname":"pai"}];
sample.map(function(item) {
item.newKeyValue = Object.getOwnPropertyNames(item).map(function(d) {return item[d];}).join("|");
})
console.log(sample);

Categories

Resources