compare nested arrays of objects - javascript

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);

Related

How to get all specific values from an array of objects with nested arrays of objects?

I have an array:
const arr = [
{
name: "name 1",
dontShow: true,
children: [
{
name: "name 2",
key4: 4,
dontShow: false,
children: [],
},
],
},
{
name: "name 3",
dontShow: false,
children: [
{
name: "name 4",
dontShow: true,
children: [
{
name: "name 5",
dontShow: false,
children: null,
},
],
},
],
},
];
I need an array of names from every object, except those that have property dontShow: true
So from that example I would expect such array:
["name2", "name3", "name5"]
Basically, I need to get a flat array from tree-like structure, lodash/underscore solutions would be also great, I just didn't find them
You can use a recursive function
const arr = [{ name: "name 1", dontShow: true, children: [{ name:"name 2", key4: 4, dontShow: false, children: [], }, ],},{name: "name 3",dontShow: false,children: [{ name: "name 4", dontShow: true, children: [{ name: "name 5", dontShow: false, children: null,},],}, ],},];
let final = (arr, result = []) => {
if (Array.isArray(arr)) {
arr.forEach(obj => {
if (!obj.dontShow) {
result.push(obj.name)
}
if (Array.isArray(obj.children)) {
final(obj.children, result)
}
})
}
return result
}
console.log(final(arr))
You could get a flat array of names with a look to dontShow.
const
getNames = array => array.flatMap(({ name, dontShow, children }) => [
...(dontShow ? [] : [name]),
...getNames(children || [])
]),
array = [{ name: "name 1", dontShow: true, children: [{ name: "name 2", key4: 4, dontShow: false, children: [] }] }, { name: "name 3", dontShow: false, children: [{ name: "name 4", dontShow: true, children: [{ name: "name 5", dontShow: false, children: null, }] }] }],
result = getNames(array);
console.log(result);

Group Json array 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));

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>

Find property in array of objects [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am trying to find an array in my object:
{setParentCategory
? <Picker
selectedValue={setSubCategory}
label="Year group"
onChange={this.onGroupChange}
options={
categories.find(category => {
category.id == setParentCategory;
}).options
}
/>
: null}
My data is like this:
[ {
id: 0,
label: "Year 1",
value: 1,
options: [
{ name: "Firm 1", id: 1 },
{ name: "Firm 2", id: 2 },
{ name: "Firm 3", id: 3 }
]
},
{
id: 1,
label: "Year 2",
value: 2,
options: [
{ name: "Firm 4", id: 4 },
{ name: "Firm 5", id: 5 },
{ name: "Firm 6", id: 6 }
]
},
{
id: 2,
label: "Year 3",
value: 3,
options: [
{ name: "Firm 7", id: 7 },
{ name: "Firm 8", id: 8 },
{ name: "Firm 9", id: 9 }
]
}
]
MY error is cannot read property 'options' of undefined.
In your find function you need to explicitly return the Boolean value you're creating.
See
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
let categories = [{
id: 0,
label: "Year 1",
value: 1,
options: [{
name: "Firm 1",
id: 1
},
{
name: "Firm 2",
id: 2
},
{
name: "Firm 3",
id: 3
}
]
},
{
id: 1,
label: "Year 2",
value: 2,
options: [{
name: "Firm 4",
id: 4
},
{
name: "Firm 5",
id: 5
},
{
name: "Firm 6",
id: 6
}
]
},
{
id: 2,
label: "Year 3",
value: 3,
options: [{
name: "Firm 7",
id: 7
},
{
name: "Firm 8",
id: 8
},
{
name: "Firm 9",
id: 9
}
]
}
]
let options = categories.find(category => {
return category.id == 2;
}).options
console.log(options)

Categories

Resources