Related
I'm using underscore.js to group my objects, now I want to add a property to work as an identifier for that group and then reduce those objects back into its original structure. But not sure how to do it.
The rule is to find who has more than one appointment in that day and add a property to it.
Something we achieved here:
https://jsfiddle.net/bjxgszmw/
with this line of code:
var resultt = _.chain(allAppointments)
.groupBy('appointment_date')
.mapObject( date => _.groupBy(date, 'email' ) )
So from what we have've got which is this:
{
"23July": {
"john#domain.com": [
{
"ap_id": 23,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 3,
"time": "morning"
},
{
"ap_id": 44,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternon"
}
],
"rose#domain.com": [
{
"ap_id": 55,
to something simple like this;
allAppointments_Filtered:
[{
"ap_id": 23,
"name": "John",
"email": "John#domain.com",
"appointment_date": "23July",
"appointment_category": 3,
"time": "morning",
hasMultipleAppointmentOnDate: "yes"
},{
"ap_id": 55,
"name": "Rose",
"email": "rose#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternoon"
hasMultipleAppointmentOnDate: "nope"
},{
"ap_id": 44,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternoon"
hasMultipleAppointmentOnDate: "yes"
},{
...
}];
Well, you don't need to do all those grouping and mappings. All you have to do is a single map and a count based on the current appointment you check:
var allAppointments = [
{
"ap_id": 23,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 3,
"time": "morning"
},
{
"ap_id": 55,
"name": "Rose",
"email": "rose#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternon"
},
{
"ap_id": 44,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternon"
},
{
"ap_id": 70,
"name": "Kate",
"email": "kate#domain.com",
"appointment_date": "29July",
"appointment_category": 4,
"time": "afternon"
}
]
var counts = {};
var result = _.mapObject(allAppointments, (appointment) => {
var key = appointment.email + appointment.appointment_date;
if (!_.has(counts, key)) {
counts[key] = _.countBy(allAppointments, (app) =>
appointment.email === app.email &&
appointment.appointment_date === app.appointment_date
).true > 1
}
appointment.hasMultipleAppointmentOnDate = counts[key];
return appointment;
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
You need to group by a composite key:
// data
const allAppointments = [
{
"ap_id": 23,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 3,
"time": "morning"
},
{
"ap_id": 55,
"name": "Rose",
"email": "rose#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternon"
},
{
"ap_id": 44,
"name": "John",
"email": "john#domain.com",
"appointment_date": "23July",
"appointment_category": 4,
"time": "afternon"
},
{
"ap_id": 70,
"name": "Kate",
"email": "kate#domain.com",
"appointment_date": "29July",
"appointment_category": 4,
"time": "afternon"
}
];
// gets grouping key, which is email + date
const groupKey = i => i.email +'_'+ i.appointment_date;
// store counts for appointments for unique (email + date)
const counts = _.countBy(allAppointments,groupKey);
// checks if appointment has more than one instances on date
const isMulti = i => counts[groupKey(i)] > 1;
// updated appointment with multiple indicator property
const multiProp = i => ({hasMultipleAppointmentOnDate: isMulti(i) ? "yes": "nope"});
// update initial array items with multiple
const updated = _.map(allAppointments,i => _.extend(i,multiProp(i)));
// see results
console.log(updated);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
I've got a graph with nodes that can be connected to multiple other nodes.
Every node represents an object in an array. Within every node's object is an array that contains the ids of all the nodes linked to this node and its depth:
nodes: [
{"id":1, "depth":0, "next":[], "children":[2, 3]}, // nodes.next = [2, 3]
{"id":2, "depth":1, "next":[], "children":[1, 4, 5]}, // nodes.next = [4, 5]
{"id":3, "depth":1, "next":[], "children":[1, 6, 7]}, // nodes.next = [6, 7]
{"id":4, "depth":2, "next":[], "children":[2, 8]}, // nodes.next = [8]
{"id":5, "depth":2, "next":[], "children":[2, 9]} // nodes.next = [9]
]
I would like to traverse the graph from a certain node.
The problem is that a node's children array contains all the nodes linked to it. A node with a depth of 2 points back to a node with a depth of 1.
So I would like to create a new array within the nodes' objects, let's say nodes.next and get rid of the children that point back to a node that has a depth lower than itself.
The part that really baffles me is checking the depth of the nodes in nodes.children. I even haven't been near the part where I might check if the depth of a node in nodes.children is higher than nodes[i].depth and push nodes[i].children[i] to nodes[i].next.
If there is better way to solve this problem I'd be happy to know. My attemps have been fruitless in many ways alike:
let childDepth;
for (let i = 0; i < nodes.length; i++) {
for (let child in nodes[i].children) {
if (nodes.id === child) {
childDepth = nodes[i].depth;
}
if (childDepth > graph.nodes[i].depth) {
nodes[i].next.push(child)
}
}
}
Updated array:
const nodes = [
{ "id": 37, "depth": 0, "children": [210, 395, 265], "next": [] },
{ "id": 210, "depth": 1, "children": [37, 260, 259, 391],"next": [] },
{ "id": 256, "depth": 2, "children": [265], "next": [] },
{ "id": 259, "depth": 2, "children": [210, 397, 396], "next": [] },
{ "id": 260, "depth": 2, "children": [210], "next": [] },
{ "id": 265, "depth": 1, "children": [37, 256, 388, 394, 271, 269], "next": [] },
{ "id": 269, "depth": 2, "children": [265], "next": [] },
{ "id": 271, "depth": 2, "children": [265], "next": [] },
{ "id": 388, "depth": 2, "children": [265], "next": [] },
{ "id": 391, "depth": 2, "children": [210], "next": [] },
{ "id": 394, "depth": 2, "children": [265], "next": [] },
{ "id": 395, "depth": 1, "children": [37], "next": [] },
{ "id": 396, "depth": 3, "children": [259, 413], "next": [] },
{ "id": 397, "depth": 3, "children": [259], "next": [] },
{ "id": 413, "depth": 4, "children": [396], "next": [] }
];
Kindly take a look on the below code to see if it's what you're looking for
const array = [
{id:1, depth:0, next:[], children:[2, 3]},
{id:2, depth:1, next:[], children:[1, 4, 5]},
{id:3, depth:1, next:[], children:[1, 6, 7]},
{id:4, depth:2, next:[], children:[2, 8]},
{id:5, depth:2, next:[], children:[2, 9]}
]
array.forEach(x => {
let { children, depth } = x;
for(let i=depth; i< children.length; i++){
x.next.push(children[i]);
}
});
Output as below:
[
{"id":1,"depth":0,"next":[2,3],"children":[2,3]},
{"id":2,"depth":1,"next":[4,5],"children":[1,4,5]},
{"id":3,"depth":1,"next":[6,7],"children":[1,6,7]},
{"id":4,"depth":2,"next":[],"children":[2,8]},
{"id":5,"depth":2,"next":[],"children":[2,9]}
]
Hi i want to use a treeView in my angularjs, the data recieved from the server is:
[
{
"vehiculeid": 1,
"name": "ggg",
"id": 1,
"group": "TGV"
},
{
"vehiculeid": 5,
"name": "eee",
"id": 5,
"group": "TGV"
},
{
"vehiculeid": 6,
"name": "tru123",
"id": 8,
"group": "TGV"
},
{
"vehiculeid": 2,
"name": "aqs",
"id": 3,
"group": "TCF"
}
]
How can i make the data like the folowing data so that i can use it in treeView Component, this is that format which i want to got:
treedata_avm = [{
group: 'TGV',
children: [{
name: 'ggg',
data: {
vehiculeid: 1
}
}, {
name: 'eee',
data: {
vehiculeid: 5
}
}, {
name: 'tru123',
data: {
vehiculeid: 6
}
}]
},{
group: 'TCF',
children: [{
name: 'aqs',
data: {
vehiculeid: 2
}
}]
}]
How i can do that with javascript or angularjs to get this format?
P.S:
the data recieved from the server is dynamic.
Here's the code:
var test = [
{
"vehiculeid": 1,
"name": "ggg",
"id": 1,
"group": "TGV"
},
{
"vehiculeid": 5,
"name": "eee",
"id": 5,
"group": "TGV"
},
{
"vehiculeid": 6,
"name": "tru123",
"id": 8,
"group": "TGV"
},
{
"vehiculeid": 2,
"name": "aqs",
"id": 3,
"group": "TCF"
}
];
var test2 = {};
for(var i in test) {
if(typeof test2[test[i]['group']] === 'undefined') {
test2[test[i]['group']] = [];
}
test2[test[i]['group']].push({name: test[i]['name'], data: {vehiculeid: test[i]['vehiculeid']}})
}
var treedata_avm = [];
for(var j in test2) {
var final = {};
final['group'] = j;
final['children'] = test2[j];
treedata_avm.push(final)
}
console.log(treedata_avm)
I'm trying to figure out how to do this in ES6...
I have this array of objects..
const originalData=[
{"investor": "Sue", "value": 5, "investment": "stocks"},
{"investor": "Rob", "value": 15, "investment": "options"},
{"investor": "Sue", "value": 25, "investment": "savings"},
{"investor": "Rob", "value": 15, "investment": "savings"},
{"investor": "Sue", "value": 2, "investment": "stocks"},
{"investor": "Liz", "value": 85, "investment": "options"},
{"investor": "Liz", "value": 16, "investment": "options"}
];
..and this new array of objects where I want to add each person's total value of their investment types (stocks, options, savings)..
const newData = [
{"investor":"Sue", "stocks": 0, "options": 0, "savings": 0},
{"investor":"Rob", "stocks": 0, "options": 0, "savings": 0},
{"investor":"Liz", "stocks": 0, "options": 0, "savings": 0}
];
I loop through originalData and save each property of the "current object" in a let..
for (let obj of originalData) {
let currinvestor = obj.investor;
let currinvestment = obj.investment;
let currvalue = obj.value;
..but here I want to find the obect in newData that has the property = currinvestor (for the "investor" key)
...then add that investment type's (currinvestment) value (currvalue)
}
newData.find(x => x.investor === investor)
And the whole code:
const originalData = [
{ "investor": "Sue", "value": 5, "investment": "stocks" },
{ "investor": "Rob", "value": 15, "investment": "options" },
{ "investor": "Sue", "value": 25, "investment": "savings" },
{ "investor": "Rob", "value": 15, "investment": "savings" },
{ "investor": "Sue", "value": 2, "investment": "stocks" },
{ "investor": "Liz", "value": 85, "investment": "options" },
{ "investor": "Liz", "value": 16, "investment": "options" },
];
const newData = [
{ "investor": "Sue", "stocks": 0, "options": 0, "savings": 0 },
{ "investor": "Rob", "stocks": 0, "options": 0, "savings": 0 },
{ "investor": "Liz", "stocks": 0, "options": 0, "savings": 0 },
];
for (let {investor, value, investment} of originalData) {
newData.find(x => x.investor === investor)[investment] += value;
}
console.log(newData);
.as-console-wrapper.as-console-wrapper { max-height: 100vh }
I would use some derivative of this:
var arrayFindObjectByProp = (arr, prop, val) => {
return arr.find( obj => obj[prop] == val );
};
Please help me with this customization of objects in javascript, I'm a little stuck.
Object
var stocks = [
{
"size": "2",
"count": 5,
"store": {
"id": 3,
"title": "Belconnen"
}
},
{
"size": "3",
"count": 4,
"store": {
"id": 4,
"title": "Canberra"
}
},
{
"size": "4",
"count": 4,
"store": {
"id": 5,
"title": "Bankstown"
}
},
{
"size": "5",
"count": 5,
"store": {
"id": 4,
"title": "Canberra"
}
}];
Expected Output
{3:{"sizes": {2: 3}}},
{4:{"sizes": {3: 3, 5: 3}}},
{5:{"sizes": {4: 3}}}
My code so far
for (var key in stocks) {
var stock = stocks[key];
stores[stock.store.id] = stock.store;
var store = stores[stock.store.id];
if (!store.sizes || !store.sizes.length) {
store.sizes = [stock.size];
}
}
But it keeps overiding the first size value of the store.
Thanks in advance.
This is one way to solve the problem
var stocks = [
{"size": 2, "count": 3, "store": {"id": 3, "name": "Canberra"}},
{"size": 3, "count": 3, "store": {"id": 4, "name": "Belconnen"}},
{"size": 4, "count": 3, "store": {"id": 5, "name": "Bankstown"}},
{"size": 5, "count": 3, "store": {"id": 4, "name": "Belconnen"}}];
var obj = {};
stocks.forEach(function(item){
// initialize if object key not present
if(!obj[item.store.id]){
obj[item.store.id] = {"sizes": {}};
}
obj[item.store.id]["sizes"][item.size] = item.count;
});
console.log(obj);
Here is the working fiddle https://jsfiddle.net/flyinggambit/nc3uny53/
Check the console window for fiddle output