Group Json array javascript - javascript

This is quite simple question, I got a Json like this:
const test = [
{
label: "Group 1",
options: [
{ label: "option 1", value: "value_1" },
{ label: "option 2", value: "value_2" }
]
},
{
label: "Group 1",
opions: [
{ label: "option 3", value: "value_3" },
{ label: "option 4", value: "value_4" }
]
},
{
label: "Group 2",
options: [
{ label: "option 5", value: "value_5" },
{ label: "option 6", value: "value_6" }
]
},
{
label: "Group 3",
options: [
{ label: "option 7", value: "value_7" },
{ label: "option 8", value: "value_8" }
]
},
{
label: "Group 3",
options: [
{ label: "option 9", value: "value_9" },
{ label: "option 10", value: "value_10" }
]
},
];
And I want to group them like this (by the Group label - the format is exactly as described below, I cannot add any other values as I'll use it in the react-select component as options)
const test = [
{
label: "Group 1",
options: [
{ label: "option 1", value: "value_1" },
{ label: "option 2", value: "value_2" },
{ label: "option 3", value: "value_3" },
{ label: "option 4", value: "value_4" }
]
},
{
label: "Group 2",
options: [
{ label: "option 5", value: "value_5" },
{ label: "option 6", value: "value_6" }
]
},
{
label: "Group 3",
options: [
{ label: "option 7", value: "value_7" },
{ label: "option 8", value: "value_8" },
{ label: "option 9", value: "value_9" },
{ label: "option 10", value: "value_10" }
]
},
];
How can I achieve that?
Thanks in advance

Please find the solution below for your problem statement.
const test = [{
label: "Group 1",
options: [{
label: "option 1",
value: "value_1"
},
{
label: "option 2",
value: "value_2"
}
]
},
{
label: "Group 1",
opions: [{
label: "option 3",
value: "value_3"
},
{
label: "option 4",
value: "value_4"
}
]
},
{
label: "Group 2",
options: [{
label: "option 5",
value: "value_5"
},
{
label: "option 6",
value: "value_6"
}
]
},
{
label: "Group 3",
options: [{
label: "option 7",
value: "value_7"
},
{
label: "option 8",
value: "value_8"
}
]
},
{
label: "Group 3",
options: [{
label: "option 9",
value: "value_9"
},
{
label: "option 10",
value: "value_10"
}
]
},
];
let temp = {};
test.forEach(t => {
const key = t.label;
if (temp[key]) {
const tempArray = temp[key].options.concat(t.options);
temp[key].options = tempArray;
} else {
temp[key] = {
label: key,
options: t.options
}
}
});
console.log(Object.values(temp));

Related

compare nested arrays of objects

Could you help me plese? I need to compare and calculate the percentage of the difference between the values ​​and return an array. I need to compare arrays, get to objects with name and value, and count the percentage. Suppose for the first item in array {name: 'Name 1', value: 1945}, go into the second item to find there {name: 'Name 1', value: 699}. The percentage for 1945 will be 100, for 699 - 36. I'm confused about nesting((
//input data
const data = [
{
_id: "0090908",
groups: [
{
_id: "24424",
name: "Group 1",
group_type: "group_1",
items: [
{ name: "Name 1", value: 1945 },
{ name: "Name 2", value: 0 },
{ name: "Name 3", value: 39 },
],
},
{
_id: "23030",
name: "Group 2",
group_type: "group_2",
items: [
{ name: "Name 4", value: 67 },
{ name: "Name 5", value: 123 },
{ name: "Name 6", value: 13 },
],
},
]
},
{
_id: "00390395",
groups: [
{
_id: "837583",
name: "Group 1",
group_type: "group_1",
items: [
{ name: "Name 1", value: 699 },
{ name: "Name 2", value: 55},
{ name: "Name 3", value: 39 },
],
},
{
_id: "8989305",
name: "Group 2",
group_type: "group_2",
items: [
{ name: "Name 4", value: 998 },
{ name: "Name 5", value: 12 },
{ name: "Name 6", value: 485 },
],
},
]
}
];
//result data
const result = [
{
_id: "0090908",
groups: [
{
_id: "24424",
name: "Group 1",
group_type: "group_1",
items: [
{ name: "Name 1", value: 1945, percent: 100, best: true },
{ name: "Name 2", value: 0, percent: 0, best: false },
{ name: "Name 3", value: 39, percent: 100, best: true },
],
},
{
_id: "23030",
name: "Group 2",
group_type: "group_2",
items: [
{ name: "Name 4", value: 67, percent: 6, best: false },
{ name: "Name 5", value: 123, percent: 100, best: true },
{ name: "Name 6", value: 13, percent: 3, best: true },
],
},
]
},
{
_id: "00390395",
groups: [
{
_id: "837583",
name: "Group 1",
group_type: "group_1",
items: [
{ name: "Name 1", value: 699, percent: 36, best: false },
{ name: "Name 2", value: 55, percent: 100, best: true},
{ name: "Name 3", value: 39, percent: 100, best: true },
],
},
{
_id: "8989305",
name: "Group 2",
group_type: "group_2",
items: [
{ name: "Name 4", value: 998, percent: 100, best: true },
{ name: "Name 5", value: 12, percent: 9, best: false },
{ name: "Name 6", value: 485, percent: 100, best: true },
],
},
]
}
];
First you need to run through all elements, finding the largest values of each name. Then you run again, placing the percentages.
var best = {}; // Our database of higher values
function checkLargest(data) {
if (!data) return;
// If is iterable perform the function on each element
if (Symbol.iterator in Object(data)) for (var el of data) checkLargest(el);
if (data.name && data.value !== undefined)
if (!best[data.name] || best[data.name] < data.value)
best[data.name] = data.value;
checkLargest(data.groups); // If doesn't exist will return
checkLargest(data.items);
}
function placePercentages(data) {
if (!data) return;
if (Symbol.iterator in Object(data)) for (var el of data) placePercentages(el);
if (data.name && data.value !== undefined) {
var higher = best[data.name];
data.percent = Math.round(data.value / higher * 100);
data.best = (higher == data.value);
}
placePercentages(data.groups);
placePercentages(data.items);
}
const d = [
{
_id: "0090908",
groups: [
{
_id: "24424",
name: "Group 1",
group_type: "group_1",
items: [
{ name: "Name 1", value: 1945 },
{ name: "Name 2", value: 0 },
{ name: "Name 3", value: 39 },
],
},
{
_id: "23030",
name: "Group 2",
group_type: "group_2",
items: [
{ name: "Name 4", value: 67 },
{ name: "Name 5", value: 123 },
{ name: "Name 6", value: 13 },
],
},
]
},
{
_id: "00390395",
groups: [
{
_id: "837583",
name: "Group 1",
group_type: "group_1",
items: [
{ name: "Name 1", value: 699 },
{ name: "Name 2", value: 55},
{ name: "Name 3", value: 39 },
],
},
{
_id: "8989305",
name: "Group 2",
group_type: "group_2",
items: [
{ name: "Name 4", value: 998 },
{ name: "Name 5", value: 12 },
{ name: "Name 6", value: 485 },
],
},
]
}
];
checkLargest(d);
placePercentages(d);
console.log(d);

How to create a nested list by limiting the functions each?

I would like to create a list of nested "ul li" but limiting the nested functions to each other.
Here is my object :
"data": [
{
"label": "dataName",
"sections": [
{
"label": "label sections 1",
"fields": [
{
"id": 1,
"name": "field 1",
"value": "value field 1"
},
{
"id": 2,
"name": "field 2",
"value": "value field 2"
}
]
},
{
"label": "label sections 2",
"fields": [
{
"id": 5,
"name": "field 3",
"value": "value field 3"
}
]
},
{
"label": "dataName2",
"sections": [
{
"label": "label sections 3",
"fields": [
{
"id": 6,
"name": "field 6",
"value": "value field 6"
},
{
"id": 7,
"name": "field 7",
"value": "value field 7"
}
]
},
{
"label": "label sections 4",
"fields": [
{
"id": 8,
"name": "field 8",
"value": "value field 8"
}
]
}
]
to turn it into a list like this:
<ul>
<li>dataName
<ul>
<li>label sections 1
<ul>
<li>field 1 : value field 1 </li>
<li>field 2 : value field 2 </li>
</ul>
</li>
<li>label sections 2
<ul>
<li>field 3 : value field 3 </li>
</ul>
</li>
</ul>
</li>
<li>dataName2
<ul>
<li>label sections 3
<ul>
<li>field 6 : value field 6 </li>
<li>field 7 : value field 7 </li>
</ul>
</li>
<li>label sections 4
<ul>
<li>field 8 : value field 8 </li>
</ul>
</li>
</ul>
</li>
</ul>
I tried to perform a function but without much success !
knowing that if the "value field" value is null, it will not be displayed
var build = function(obj) {
var list = '';
_.each(obj, function (elt) {
list+='<li><em>'+elt.label+'</em></li>';
_.each(elt.sections, function (elt) {
var list2 = '';
list2+='<li><em>'+elt.label+'</em></li>';
_.each(elt.fields, function (elt) {
var list3 = '';
if(!_.isNull(elt.value)) {
list3 += '<li><em>' + elt.name
+' ' + elt.value + '</em></li>';
}
list2+='<ul>'+list3+'</ul>';
});
list+='<ul>'+list2+'</ul>';
});
});
return '<ul style="text-align: left">'+list+'</ul>';
}
if you know a more effective solution, I'm interested
You could use a dynamic approach in plain Javascript with a recursive function, which takes an array of list elements and the target element and creates new objects.
function createList(array, target) {
var ul = document.createElement('ul');
array.forEach(o => {
var li = document.createElement('li');
li.appendChild(document.createTextNode('id' in o
? `${o.name} : ${o.value}`
: o.label
));
if (o.sections || o.fields) createList(o.sections || o.fields, li);
ul.appendChild(li);
});
target.appendChild(ul);
}
var data = [{ label: "dataName", sections: [{ label: "label sections 1", fields: [{ id: 1, name: "field 1", value: "value field 1" }, { id: 2, name: "field 2", value: "value field 2" }] }, { label: "label sections 2", fields: [{ id: 5, name: "field 3", value: "value field 3" }] }, { label: "dataName2", sections: [{ label: "label sections 3", fields: [{ id: 6, name: "field 6", value: "value field 6" }, { id: 7, name: "field 7", value: "value field 7" }] }, { label: "label sections 4", fields: [{ id: 8, name: "field 8", value: "value field 8" }] }] }] }];
createList(data, document.body);
Try like this.
var arr = [{ label: "dataName", sections: [{ label: "label sections 1", fields: [{ id: 1, name: "field 1", value: "value field 1" }, { id: 2, name: "field 2", value: "value field 2" }] }, { label: "label sections 2", fields: [{ id: 5, name: "field 3", value: "value field 3" }] }, { label: "dataName2", sections: [{ label: "label sections 3", fields: [{ id: 6, name: "field 6", value: "value field 6" }, { id: 7, name: "field 7", value: "value field 7" }] }, { label: "label sections 4", fields: [{ id: 8, name: "field 8", value: "value field 8" }] }] }] }];
var content = "";
function formatData(arr){
arr.forEach(function(elem,i){
if(elem.label){
content += "<ul><li>"+elem.label;
if(elem.sections){
formatData(elem.sections);
} else if(elem.fields){
formatData(elem.fields);
}
content += "</li></ul>";
} else {
content += "<ul><li>" + elem.name + " : " + elem.value + "</li></ul>";
}
})
}
formatData(arr);
$('#datas').html(content)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="datas"></div>

Recursively get full path (parents hierarchy) of a given node in a nested object

I need a typescript function to recursively get the full path (parent hierarchy) of a given node by passing its value.
Let's say I have an array of objects like this:
items = [{
value: 2,
text: "Name 2",
children: [{
value: 7,
text: "Name 7",
children: [{
value: 10,
text: "Name 10",
children: []
},
{
value: 11,
text: "Name 11",
children: []
},
{
value: 12,
text: "Name 12",
children: [{
value: 13,
text: "Name 13",
children: [{
value: 14,
text: "Name 14",
children: []
},
{
value: 15,
text: "Name 15",
children: []
}
]
}]
}
]
}]
},
{
value: 16,
text: "Name 16",
children: [{
value: 17,
text: "Name 17",
children: [{
value: 18,
text: "Name 18",
children: []
},
{
value: 19,
text: "Name 19",
children: []
}
]
}]
}
];
Let's say I want to get the full path of node with value=19 by calling a function.
getPath(items, 19);
The expected result could be either returning only values of parent nodes
[16, 17, 19]
or array of objects as bellow:
[{
value: 16,
text: "Name 16"
},
{
value: 17,
text: "Name 17"
},
{
value: 19,
text: "Name 19"
}
]
Thanks,
Hope this help
const items = [{
value: 2,
text: "Name 2",
children: [{
value: 7,
text: "Name 7",
children: [{
value: 10,
text: "Name 10",
children: []
},
{
value: 11,
text: "Name 11",
children: []
},
{
value: 12,
text: "Name 12",
children: [{
value: 13,
text: "Name 13",
children: [{
value: 14,
text: "Name 14",
children: []
},
{
value: 15,
text: "Name 15",
children: []
}
]
}]
}
]
}]
},
{
value: 16,
text: "Name 16",
children: [{
value: 17,
text: "Name 17",
children: [{
value: 18,
text: "Name 18",
children: []
},
{
value: 19,
text: "Name 19",
children: []
}
]
}]
}
];
function getPath(items, val) {
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.value !== val) {
if (item.children) {
const path = getPath(item.children, val);
if (path) {
path.unshift(item.value);
return path;
}
}
} else {
return [item.value];
}
}
}
console.log(getPath(items, 19));
Here's the link for it

Uncaught FoamTree: element has zero dimensions: 522 x 0

if (CarrotSearchFoamTree.supported) {
var foamtree = new CarrotSearchFoamTree({
id: "visualization",
dataObject: {
groups: [
{ id: "1", label: "Group 1", groups: [
{ id: "1.1", label: "Group 1.1" },
{ id: "1.2", label: "Group 1.2" }
]},
{ id: "2", label: "Group 2", groups: [
{ id: "2.1", label: "Group 2.1" },
{ id: "2.2", label: "Group 2.2" }
]},
{ id: "3", label: "Group 3", groups: [
{ id: "3.1", label: "Group 3.1" },
{ id: "3.2", label: "Group 3.2" }
]},
{ id: "4", label: "Group 4", groups: [
{ id: "4.1", label: "Group 4.1" },
{ id: "4.2", label: "Group 4.2" }
]},
{ id: "5", label: "Group 5", groups: [
{ id: "5.1", label: "Group 5.1" },
{ id: "5.2", label: "Group 5.2" }
]}
]
}
});
} else {
console.log("Visualization not supported.");
}
carrot search issue in carrotsearch.foamtree.js :Uncaught FoamTree: element has zero dimensions: 522 x 0.
this is a sample code for carrotsearch any help will be appreciated
you need to define an HTML element in which FoamTree should be embedded. The element must have non-zero dimensions.
see example:
<html>
<body>
<div id="visualization" style="width: 800px; height: 600px"></div>
<script src="https://get.carrotsearch.com/foamtree/demo/carrotsearch.foamtree.js">
</script>
<script>
window.addEventListener("load", function() {
var foamtree = new CarrotSearchFoamTree({
id: "visualization",
dataObject: {
groups: [
{ label: "Your", weight: 1.0 },
{ label: "First", weight: 3.0 },
{ label: "FoamTree", weight: 2.0 },
{ label: "Visualization", weight: 4.0 }
]
}
});
});
</script>

How to map an array object with key from different array set in javascript

I'm building a small application in VueJS where I'm getting a response in following format:
"meeting_summaries":[
{
"interaction_id":22,
"nature":"1",
"client_name":"Test Company 4",
},
{
"interaction_id":22,
"nature":"2",
"client_name":"Test Company 5",
}
]
And I'm having a data set of nature as:
const nature = [
{value: 1, label: "Demo 1"},
{value: 2, label: "Demo 2"},
{value: 3, label: "Demo 3"}
]
I want to map my meeting_summaries with this data set were in meeting_summaries -> nature points to nature -> value so that my final output can look something like this:
"meeting_summaries":[
{
"interaction_id":22,
"nature":"1",
'nature_name": "Demo 1",
"client_name":"Test Company 4",
},
{
"interaction_id":22,
"nature":"2",
'nature_name": "Demo 2",
"client_name":"Test Company 5",
}
]
You could use a hash table and then iterate the meeting_summaries.
const object = { meeting_summaries: [{ interaction_id: 22, nature: "1", client_name: "Test Company 4" }, { interaction_id: 22, nature: "2", client_name: "Test Company 5", mention_name: "Analyst" }] },
nature = [{ value: 1, label: "Demo 1" }, { value: 2, label: "Demo 2" }, { value: 3, label: "Demo 3" }],
natureMap = Object.assign(...nature.map(o => ({ [o.value]: o.label })));
object.meeting_summaries.forEach(o => o.nature_name = natureMap[o.nature]);
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Just map through array an add your property using Object.assing and Array.prototype.find:
const a = {
"meeting_summaries":[
{
"id":1,
"company_id":7,
"interaction_id":22,
"nature":"1",
"user_id":1,
"action":"Action Test 1",
"feedback":"Comment Test 1",
"created_at":"2017-06-04 10:15:02",
"updated_at":"2017-06-04 10:15:02",
"deleted_at":null,
"client_name":"Test Company 4",
"mention_name":"Analyst"
},
{
"id":2,
"company_id":8,
"interaction_id":22,
"nature":"2",
"user_id":1,
"action":"Action Test 2",
"feedback":"Comment Test 2",
"created_at":"2017-06-04 10:15:02",
"updated_at":"2017-06-04 10:15:02",
"deleted_at":null,
"client_name":"Test Company 5","mention_name":"Analyst"
}
]
};
const nature = [
{value: 1, label: "Demo 1"},
{value: 2, label: "Demo 2"},
{value: 3, label: "Demo 3"},
{value: 4, label: "Demo 4"},
{value: 5, label: "Demo 5"}
]
const res = a.meeting_summaries.map(ms => Object.assign(ms,
(nature.find(n => n.value == ms.nature)) // if corresponding object exists
? { nature_name: nature.find(n => n.value == ms.nature).label } : {}
))
console.log(res)
You didn't provide full context, but let's assume that "meeting_summaries" is variable:
var meeting_summaries = [{
"interaction_id": 22,
"nature": "1",
"client_name": "Test Company 4",
},
{
"interaction_id": 22,
"nature": "2",
"client_name": "Test Company 5",
"mention_name": "Analyst"
}
]
const nature = [
{ value: 1, label: "Demo 1" },
{ value: 2, label: "Demo 2" },
{ value: 3, label: "Demo 3" }
]
var meeting_summaries = meeting_summaries.map(ms => {
ms.nature_name = nature.find(n => ms.nature == n.value).label;
return ms
})
console.log(meeting_summaries)
I'm just take a "map" approach in my solution for better performance:
const meeting_summaries = [ { "interaction_id":22, "nature":"1", "client_name":"Test Company 4", }, { "interaction_id":22, "nature":"2", "client_name":"Test Company 5", } ];
const nature = [ {value: 1, label: "Demo 1"}, {value: 2, label: "Demo 2"}, {value: 3, label: "Demo 3"} ];
const natureMap = nature.reduce((accum,current)=>{
accum[current.value] = current.label;
return accum;
}, { });
const result = meeting_summaries.map(item => {
item.nature_name = natureMap[item.nature];
return item;
});
console.log(result)
Sorry for indentation, coded from smartphone
const baseObj = {
"meeting_summaries": [
{
"interaction_id": 22,
"nature": "1",
"client_name": "Test Company 4",
},
{
"interaction_id": 22,
"nature": "2",
"client_name": "Test Company 5",
}
]
}
const natures = [
{value: 1, label: "Demo 1"},
{value: 2, label: "Demo 2"}
]
const meeting_summaries = baseObj.meeting_summaries
natures.forEach((nature, index) => {
meeting_summaries[index]["nature_name"] = nature.label
})
console.log(baseObj)
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do Array.prototype.forEach() and add the nature_name property of the found element label:
const nature = [{value: 1, label: "Demo 1"},{value: 2, label: "Demo 2"},{value: 3, label: "Demo 3"}];
const obj = {meeting_summaries: [{"interaction_id":22,"nature":"1","client_name":"Test Company 4",},{"interaction_id":22,"nature":"2","client_name":"Test Company 5"}]};
obj.meeting_summaries.forEach(el => el.nature_name = nature.find(n => n.value == el.nature).label);
console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories

Resources