Related
There can two sets of objects
First can be a straight forward where is no children
const noChildObj = [{
"id": 1,
"label": ["Description"],
"lines": 1,
"type": "string",
"precision": 2,
"width": 167.8
}, {
"id": 2,
"label": ["Information", "Ratio"],
"lines": 2,
"type": "number",
"precision": 2,
"width": 167.8
}, {
"id": 3,
"label": ["Tracking", "Error"],
"lines": 2,
"type": "number",
"precision": 2,
"width": 167.8
}]
So,in this case, there is no child , so property 'width' is at the topmost layer.
Second is where nesting of objects occur
So each object in the array will have a child object
[{
"id": "257",
"label": [""],
"lines": 1,
"children": [{
"id": "Description",
"label": ["Dates"],
"lines": 1,
"type": "date",
"precision": null,
"width": 839
}]
}, {
"id": "258",
"label": ["Cumulative Return"],
"lines": 1,
"children": [{
"id": 12,
"label": ["Russell 1000 Value - Price Return"],
"lines": 1,
"type": "number",
"precision": 2,
"width": 839
}]
}]
Here each object has a child object where the property width exists
This nesting is not limited to just 1 level
It can go upto 4 levels
So my use case requires if the innermost child has width undefined or not
I do realise that through recursion , we can traverse and find out..
But is there any function which can do it in less lines of code..may be in lodash
Please help
Know only how to do with recursion:
const objArray = [{
"id": 1,
"label": ["Description"],
"lines": 1,
"type": "string",
"precision": 2,
"width": 167.8
}, {
"id": "257",
"label": [""],
"lines": 1,
"children": [{
"id": "Description",
"label": ["Dates"],
"lines": 1,
"type": "date",
"precision": null,
"width": 839
}]
}]
const getWidthDeep = (el) => el.children && el.children[0]
? getWidthDeep(el.children[0])
: el.width
const result = objArray.map(getWidthDeep)
console.log(result)
I have an flowchart input using jquery flowchart library like so:
Flowchart
I get the data representation as this:
{
"operators": {
"0": {
"properties": {
"title": "Start",
"inputs": {},
"outputs": {
"outs": {
"label": "Output (:i)",
"multiple": true
}
},
"class": "start-operator"
},
"top": 0,
"left": 0
},
"1": {
"properties": {
"title": "End",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {},
"class": "end-operator"
},
"top": null,
"left": null
},
"37": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 0
},
"38": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 580,
"top": 0
},
"39": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 920,
"top": 0
},
"40": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 100
},
"41": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 200
},
"42": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 620,
"top": 140
},
"43": {
"properties": {
"title": "POS",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 740,
"top": 320
}
},
"links": {
"0": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 0,
"toOperator": 37,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #e53935"
},
"1": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 1,
"toOperator": 40,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #d81b60"
},
"2": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 2,
"toOperator": 41,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #8e24aa"
},
"3": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 3,
"toOperator": 43,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #5e35b1"
},
"4": {
"fromOperator": 37,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 38,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #3949ab"
},
"5": {
"fromOperator": 40,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #546e7a"
},
"6": {
"fromOperator": 41,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #039be5"
},
"7": {
"fromOperator": 38,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #00acc1"
},
"8": {
"fromOperator": 42,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #00897b"
},
"9": {
"fromOperator": 39,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 0,
"color": " #43a047"
},
"10": {
"fromOperator": 43,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 1,
"color": " #7cb342"
}
},
"operatorTypes": {}
}
I want to use this for filtering data in tabulator so turn this into this:
[
{
"id": 1,
"pid": null
},
{
"id": 39,
"pid": 1
},
{
"id": 38,
"pid": 39
},
{
"id": 37,
"pid": 38
},
{
"id": 42,
"pid": 39
},
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
},
{
"id": 43,
"pid": 1
}
]
Then using this lines I turned into a tree:
const idMapping = data.reduce((acc, el, i) => {
acc[el.id] = i;
return acc;
}, {});
let root;
data.forEach(el => {
// Handle the root element
if (el.pid === null) {
root = el;
return;
}
// Use our mapping to locate the parent element in our data array
const parentEl = data[idMapping[el.pid]];
// Add our current el to its parent's `children` array
parentEl.children = [...(parentEl.children || []), el];
});
Here it is as a tree:
{
"id": 1,
"pid": null,
"children": [
{
"id": 39,
"pid": 1,
"children": [
{
"id": 38,
"pid": 39,
"children": [
{
"id": 37,
"pid": 38
}
]
},
{
"id": 42,
"pid": 39,
"children": [
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
}
]
}
]
},
{
"id": 43,
"pid": 1
}
]
}
Hovewer I want to simplify this further to just nested arrays of the id's. Like this:
[
1,
[
[
39,
[
[
38,
[
37
],
],
[
42,
[
40,
41
]
]
]
],
43
]
]
Question is, how to convert from tree to nested array?
You can use recursion to do this; leaf ids are passed upward without an array wrapper while interior node ids are wrapped in an array with a second element for their children.
const tree = { "id": 1, "pid": null, "children": [ { "id": 39, "pid": 1, "children": [ { "id": 38, "pid": 39, "children": [ { "id": 37, "pid": 38 } ] }, { "id": 42, "pid": 39, "children": [ { "id": 40, "pid": 42 }, { "id": 41, "pid": 42 } ] } ] }, { "id": 43, "pid": 1 } ] };
const objTreeToArrTree = node =>
node.children
? [node.id].concat([node.children.map(objTreeToArrTree)])
: node.id
;
console.log(JSON.stringify(objTreeToArrTree(tree), null, 2));
I am trying to format data that I send to an endpoint. Currently the endpoint expects a certain format but the data that I am sending does not match that entirely. The data I am sending has extra brackets. Please see my code below versus what it expected.
What I am sending
[
[
{
"corporateId": "97765c76-19c3-48b5-8183-d450e72e8f23",
"selectedMAP": [
{
"mapId": 53,
"mapName": "Discovery",
"active": true,
"options": [
{
"optionId": 81,
"optionName": "Keycare",
"memberAmount": 1000,
"adultDependantAmount": 500,
"childDependantAmount": 500,
"active": true
}
]
},
{
"mapId": 54,
"mapName": "Bestmed",
"active": true,
"options": [
{
"optionId": 83,
"optionName": "Beat 1",
"memberAmount": 1000,
"adultDependantAmount": 500,
"childDependantAmount": 500,
"active": true
},
{
"optionId": 84,
"optionName": "Beat 2",
"memberAmount": 2000,
"adultDependantAmount": 1000,
"childDependantAmount": 1000,
"active": true
}
]
}
]
}
],
{
"gapCoverProviders": [
{
"id": 0,
"name": "a",
"isActive": true,
"gapCoverOptions": [
{
"id": 0,
"name": "b",
"optionPrice": 111,
"isActive": true
}
]
}
]
}
]
What is expected
{
"corporateId": "string",
"active": true,
"selectedMAP": [
{
"mapId": 0,
"mapName": "string",
"active": true,
"options": [
{
"optionId": 0,
"optionName": "string",
"memberAmount": 0,
"adultDependantAmount": 0,
"childDependantAmount": 0,
"active": true
}
]
}
],
"gapCoverProviders": [
{
"id": 0,
"name": "string",
"isActive": true,
"gapCoverOptions": [
{
"id": 0,
"name": "string",
"isActive": true,
"optionPrice": 0
}
]
}
]
}
I build the structure that is being posted as follows. I have 2 models which I then combine into 1 data set.
model 1
export class CompanyMedicalAidProvider {
corporateId: string;
active: boolean = true;
selectedMAP: Array<SelectedMap>;
}
model 2
export class CompanyGapCoverProvider {
gapCoverProviders: Array<GapCoverProviders>;
}
data that gets posted
data = [this.companyMedicalAidProvider, this.companyGapCoverProvider];
Any ideas how i can go about changing the structure? I am stuck on this part.
You can create new Data in required format like this
var data = [
[
{
"corporateId": "97765c76-19c3-48b5-8183-d450e72e8f23",
"selectedMAP": [
{
"mapId": 53,
"mapName": "Discovery",
"active": true,
"options": [
{
"optionId": 81,
"optionName": "Keycare",
"memberAmount": 1000,
"adultDependantAmount": 500,
"childDependantAmount": 500,
"active": true
}
]
},
{
"mapId": 54,
"mapName": "Bestmed",
"active": true,
"options": [
{
"optionId": 83,
"optionName": "Beat 1",
"memberAmount": 1000,
"adultDependantAmount": 500,
"childDependantAmount": 500,
"active": true
},
{
"optionId": 84,
"optionName": "Beat 2",
"memberAmount": 2000,
"adultDependantAmount": 1000,
"childDependantAmount": 1000,
"active": true
}
]
}
]
}
],
{
"gapCoverProviders": [
{
"id": 0,
"name": "a",
"isActive": true,
"gapCoverOptions": [
{
"id": 0,
"name": "b",
"optionPrice": 111,
"isActive": true
}
]
}
]
}
]
var newData = data[0][0]
newData['gapCoverProviders'] = data[1]['gapCoverProviders'];
console.log(newData)
I have JSON like this inside the main Array Object
obj = [{{"title":"1-Introduction"},
{"title":"5-Introduction"},
{"title":"20-Introduction"},
{"title":"4-Introduction"} }]
I want to sort the above object like
obj = [{{"title":"1-Introduction"},
{"title":"4-Introduction"},
{"title":"5-Introduction"},
{"title":"20-Introduction"} }]
what I have tried so far
$scope.checkWeightage=function(){
thisObj.scheduleSubject.map(itm=>itm.sectionRange.map(subItm=>{
var min = subItm.chapterActualWeightage-(subItm.chapterActualWeightage/10);
var max = subItm.chapterActualWeightage+(subItm.chapterActualWeightage/10);
var sum = subItm.items.reduce((total,it)=>{
return total+it.actualWeightage;
},0);
subItm['weightageError'] = (sum>max || sum<min)?true:false;
subItm['ChapterActualWeightageCurrently'] = parseFloat(Math.round(sum*100)/100);
subItm.items.sort((a,b)=>a.title.split(/_(.+)/)[0]>b.title.split(/_(.+)/)[0]);
})
); console.log(thisObj.scheduleSubject[0].chapterData); //.1[0].title);
//console.log("CHECK weightage",thisObj.scheduleSubject);
}
How to track title on my main Array
alert(thisObj.scheduleSubject[0].sectionRange[0].items[0].title);
I want to sort all the items on the base of its title digits before - character example 1- , 2- ,3- ,4-, 5-, 6-, 21-,56- and so on.
Main Array Structure
[
{
"id": "25",
"section": "1",
"sectionRange": [
{
"sectionNumber": 1,
"effectAllowed": "all",
"Date": "",
"items": [
{
"subjectId": 25,
"section": 1,
"chapterId": 283,
"actualWeightage": 3.42,
"totalPaperMarks": 132,
"title": "10-Creation & Registration of Charges",
"$$hashKey": "object:146"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 284,
"actualWeightage": 2.23,
"totalPaperMarks": 132,
"title": "11-Allotment of Securities & Issue of Certificates",
"$$hashKey": "object:147"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 285,
"actualWeightage": 1.37,
"totalPaperMarks": 132,
"title": "12-Membership in a Company",
"$$hashKey": "object:148"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 286,
"actualWeightage": 3.42,
"totalPaperMarks": 132,
"title": "13-Transfer & Transmission of Securities",
"$$hashKey": "object:149"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 287,
"actualWeightage": 7.53,
"totalPaperMarks": 132,
"title": "14-Institution of Directors",
"$$hashKey": "object:150"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 288,
"actualWeightage": 1.37,
"totalPaperMarks": 132,
"title": "15-Independent Directors",
"$$hashKey": "object:151"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 289,
"actualWeightage": 13.35,
"totalPaperMarks": 132,
"title": "16-Board & its Powers",
"$$hashKey": "object:152"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 290,
"actualWeightage": 8.22,
"totalPaperMarks": 132,
"title": "17-Appointment & Remuneration of Key Managerial Personnel",
"$$hashKey": "object:153"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 291,
"actualWeightage": 6.68,
"totalPaperMarks": 132,
"title": "18-General Meetings",
"$$hashKey": "object:154"
},
{
"subjectId": 25,
"section": 1,
"chapterId": 292,
"actualWeightage": 1.37,
"totalPaperMarks": 132,
"title": "19-Loans & Investments by Companies",
"$$hashKey": "object:155"
}
You can split on that char and sort via that (assuming your main data structure is named structure:
structure.forEach(s => {
s.sectionRange.forEach(sr => {
sr.items.sort(function(a, b) {
let aParts = a.split("-"),
bParts = b.split("-");
return +aParts[0] - +bParts[0];
});
});
});
Just extract those number values and let orderBy filter of angularjs do the job for you
JS
$scope.getNumber = function(row){
var value = row.title.split("-")[0];
return parseInt(value);
};
html
<div ng-repeat="item in data | orderBy:getNumber:false">{{item.title}}</div>
also orderBy takes a second parameter (true / false) for asc / desc ordering
Demo
You can use a Array.prototype.sort with a simple sort function in which you parse the title value of each object in the array as an int and compare. Something like this:
var arr = [{
"title": "1-Introduction"
},
{
"title": "5-Introduction"
},
{
"title": "20-Introduction"
},
{
"title": "4-Introduction"
}
];
arr.sort(function(a, b) {
const aVal = parseInt(a.title.split("-")[0]);
const bVal = parseInt(b.title.split("-")[0]);
return aVal - bVal;
});
console.log(arr);
It seems that machine learning via JavaScript is in it's infancy as there are hardly any libraries which fit each other calculation wise and visualization wise.
I am using figue.js library and wish to output the result via the following:
http://www.meccanismocomplesso.org/en/dendrogramma-d3-parte1/
http://www.meccanismocomplesso.org/en/dendrogramma-d3-parte2/
http://www.meccanismocomplesso.org/en/dendrogramma-d3-parte3/
This is what it requires:
{
"name": "root", "y" : 0,
"children": [
{
"name": "parent A", "y" : 30,
"children": [
{"name": "child A1", "y" : 100},
{"name": "child A2", "y" : 100},
{"name": "child A3", "y" : 100}
]
},{
"name": "parent B", "y" : 76,
"children": [
{"name": "child B1", "y" : 100},
{"name": "child B2", "y" : 100} // <--- number at the end is the ultrametric distance
]
}
]
}
This is what figue.js is giving me(of course it's different, all of the developers do this...):
{
"label": -1,
"left": {
"label": "Point 1",
"left": null,
"right": null,
"dist": 0,
"centroid": [
13.0406203,
55.606759100000005
],
"size": 1,
"depth": 0
},
"right": {
"label": -1,
"left": {
"label": -1,
"left": {
"label": -1,
"left": {
"label": "Point 2",
"left": null,
"right": null,
"dist": 0,
"centroid": [
13.0403852,
55.6066934
],
"size": 1,
"depth": 0
},
"right": {
"label": "Point 5",
"left": null,
"right": null,
"dist": 0,
"centroid": [
13.0404121,
55.6066418
],
"size": 1,
"depth": 0
},
"dist": 0.00005819080683319214,
"centroid": [
13.04039865,
55.606667599999994
],
"size": 2,
"depth": 1
},
"right": {
"label": "Point 3",
"left": null,
"right": null,
"dist": 0,
"centroid": [
13.0404818,
55.606629700000006
],
"size": 1,
"depth": 0
},
"dist": 0.00007074249076717127, // <--- ultrametric distance
"centroid": [
13.040426366666667,
55.60665496666667
],
"size": 3,
"depth": 2
},
"right": {
"label": "Point 4",
"left": null,
"right": null,
"dist": 0,
"centroid": [
13.0405408,
55.6066934
],
"size": 1,
"depth": 0
},
"dist": 0.00008682562985036432,
"centroid": [
13.040454975000001,
55.606664574999996
],
"size": 4,
"depth": 3
},
"dist": 0.00010313457228779574,
"centroid": [
13.040488040000003,
55.606683479999994
],
"size": 5,
"depth": 4
}
I can say that this is complicated to resolve. Or does anyone know of any libraries that may compile the structure?
var root = figue.figue.agglomerate(figueLabels, figueVectors, figue.figue.EUCLIDIAN_DISTANCE, figue.figue.SINGLE_LINKAGE);
// the above code is from figue.js, I have however modified the library so that it is module and works in nodejs
// the code below is the adapter
function recursive(json) {
var str;
if (json.left !== null || json.right !== null) {
str = {
name: '',
y: json.dist,
children: []
};
if (json.left !== null) {
str.children.push(recursive(json.left));
}
if (json.right !== null) {
str.children.push(recursive(json.right));
}
} else {
str = {
name: json.label,
y: json.dist
};
}
return str;
}
var json = recursive(root);
// there we go, now we can use the json variable as an argument for the visualization
console.log(JSON.stringify(json));
Below is the result!