I use a fake api with this json, I still haven't been able to with this function, I need to convert the structure to look like this and I need to convert this data and then unconvert when saving
so that I change the parameters blockId to id, blockParent to parent.
{
"blocks": [
{
"blockId": "12",
"name": "Sierra",
"abrv": "Sir",
"blockParent": "0"
},
{
"blockId": "23",
"name": "Velasco",
"abrv": "Vel",
"blockParent": "12"
},
{
"blockId": "32",
"name": "UnitOne",
"abrv": "Uni",
"blockParent": "23"
},
{
"blockId": "48",
"name": "Vani",
"abrv": "Van",
"blockParent": "12"
},
{
"blockId": "57",
"name": "UnitTwo",
"abrv": "UniTwo",
"blockParent": "48"
}
]
}
const flatToTree = (blocks: IListBlocks[]) => {
const array: IListBlocks[] = []
const children: IListBlocks[] = []
blocks.forEach((block) => {
if (block.blockParent === block.blockId) {
array.push(block)
} else {
children.push(block)
}
})
array.forEach((block) => {
block.children = children.filter(
(child) => child.blockParent === block.blockId,
)
})
return array
}
{
"id": "12",
"title": "Sierra",
"subtitle": "Sir",
"parent": "0",
"children": [
{
"id": "13",
"title": "Sierra",
"subtitle": "Sir",
"parent": "12",
}
]
}
My code's output is like this:
let myArray = [{"num": "2", "name": "Jhon"}, {"num": "1", "name": "Sara"}, {"num": "2", "name": "Domnic"}, {"num": "3", "name": "Bravo"}]
How can I access value of num in each field of the list and if num: 2, change its value to 5?
Use Array.forEach to change the original Array
let myArray = [{ "num": "2", "name": "Jhon" }, { "num": "1", "name": "Sara" }, { "num": "2", "name": "Domnic" }, { "num": "3", "name": "Bravo" }]
myArray.forEach((node) => node.num = node.num == "2" ? "5" : node.num);
console.log(myArray);
If you want to create a new array from the existing one, Use Array.map
let myArray = [{ "num": "2", "name": "Jhon" }, { "num": "1", "name": "Sara" }, { "num": "2", "name": "Domnic" }, { "num": "3", "name": "Bravo" }]
const newArray = myArray.map(({ ...node }) => node.num = node.num == "2" ? "5" : node.num);
console.log(newArray);
Please Note: Do not forget to use spread syntax ({ ...node }) else your original array will be modified here.
You could use array map:
let myArray = [{
"num": "2",
"name": "Jhon"
}, {
"num": "1",
"name": "Sara"
}, {
"num": "2",
"name": "Domnic"
}, {
"num": "3",
"name": "Bravo"
}]
const result = myArray.map(({...item}) => {
if (item.num == 2)
item.num = "5"
return item
})
console.log(result)
How can I remove sub-objects?
[{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory": [{
"2kg": "5",
"5kg": "5",
"10kg": "5",
"20kg": "5",
"productId": "1"
}]
}]
[{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory_2kg": "5",
"current_inventory_5kg": "5",
"current_inventory_10kg": "5",
"current_inventory_20kg": "5",
}]
Use Object.keys() and a forEach loop
var x =[
{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory": [
{
"2kg": "5",
"5kg": "5",
"10kg": "5",
"20kg": "5",
"productId": "1"
}
]
}
]
x[0].current_inventory.forEach(e=>{
Object.keys(e).forEach(j=>{
x[0]['current_inventory_'+j]=e[j];
})
delete x[0].current_inventory
})
console.log(x)
Use Object.entries and reduce will simplify.
const data = [
{
id: "1",
desc: "SOME PRODUCT",
codigo: "CODE-28",
codigoBarras: "2000000001",
unidade: "PCT",
price: "24.15",
current_inventory: [
{
"2kg": 5,
"5kg": 5,
"10kg": 5,
"20kg": 5,
productId: 1
}
]
}
];
const [first] = data;
const updated = Object.entries(first).reduce((acc, [key, value]) => {
if (Array.isArray(value)) {
value.forEach(item =>
Object.entries(item).forEach(
([cKey, cValue]) => (acc[`${key}_${cKey}`] = cValue)
)
);
} else {
acc[key] = value;
}
return acc;
}, {});
console.log(updated);
THANK YOU VERY MUCH!!!
Solved using the code below:
data is de object
estoqueFracionado is the sub-object
for (let [key, value] of Object.entries(data)) {
value.estoqueFracionado.forEach (e => {
Object.keys(e).forEach(j => {
value['estoqueFracionado_' + j] = e[j]
})
delete value.estoqueFracionado
})
}
I have an array of objects, like so:
[
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
In the future this array will contain much more objects.
I'm trying to solve this using map and for it seems to be quite complicated.
That's the challenge:
how I can count how many objects have certain value? How can I get to know how many times someone booked something to day===1? The best result would be an array like this:
[{dayOne: 2}, {dayTwo: 5}, {dayThree:1}.......and so on],
where value is the value of how many times a day was booked(key), hence how many times certain object(with certain value) has appeared in the array?
Thank you in advance!
To count objects by a condition, you can use .filter --
let firstDayCount = arr.filter(x => x.day === "1").length;
To group the result by days, you can use .reduce --
let countByDays =
arr.reduce((res, { day }) => {
res[day] = res[day] || 0;
res[day] += 1;
return res;
}, {});
If you want to format your output, you can then use a dictionary of names --
let dayNames = { 1: "dayOne", 2: "dayTwo" /* and so on */}
let formattedResult =
Object.keys(countByDays)
.map(n => { [dayNames[n]]: countByDays[n] });
Note that using a .filter for counting creates an intermediate throw-away array. We're not storing a reference anywhere, so it has to be GCed soon, but if it really affects your performance measurably in a real-life scenario, you can use a .reduce instead -- something that is called "deforestation":)
let count = arr.reduce((cnt, el) => el.day === "1" ? cnt += 1 : cnt, 0);
It'll still create an intermediate anonymous object though -- a reducer function -- so if your profiler shows this place as a bottleneck, you might be best off using a for loop. As always in such cases, it's up to you to find the right spot between performance and readability in your own real-world scenarios.
To get result exactly in that format you can do this.
const objs = [
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
const days = [['dayOne', 1], ['dayTwo', 2], ['dayThree', 3]];
const res = days.reduce((acc, v) => {
const obj = {};
obj[v[0]] = objs.filter(x => x.day == v[1]).length;
return acc.concat(obj);
}, []);
console.log(res);
Note that you will need to extend the days array for every day you want to include like that. So If you want to include all 31 possible days, you need this.
const objs = [
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
const days = [['dayOne', 1], ['dayTwo', 2], ['dayThree', 3], ['dayFour', 4], ['dayFive', 5],
['daySix', 6], ['daySeven', 7], ['dayEight', 8], ['dayNine', 9], ['dayTen', 10],
['dayEleven', 11], ['dayTwelve', 12], ['dayThirten', 13], ['dayFourteen', 14],
['dayFifteen', 15], ['daySixteen', 16], ['daySeventeen', 17], ['dayEighteen', 18],
['dayNineteen', 19], ['dayTwenty', 20], ['dayTwentyone', 21], ['dayTwentytwo', 22],
['dayTwentythree', 23], ['dayTwentyfour', 24], ['dayTwentyfive', 25], ['dayTwentysix', 26],
['dayTwentyseven', 27], ['dayTwentyeight', 28], ['dayTwentynine', 29], ['dayThirty', 30],
['dayThirtyone', 31]];
const res = days.reduce((acc, v) => {
const obj = {};
obj[v[0]] = objs.filter(x => x.day == v[1]).length;
return acc.concat(obj);
}, []);
console.log(res);
Which in this example returns [{dayOne: 2}, {dayTwo: 0}, ..., {daySeventeen}: 1, {dayNineteen: 0}, ...]
An alternative is using the function reduce to group and count.
const array = [{"_id": "5b09cc3495cb6c0487f1166b","name": "ccc","email": "ccc#gmail.com","phone": "790467522","kidsNo": "1","adultsNo": "1","fullDate": "2018/5/1","year": "2018","month": "5","day": "1","chosenHour": "11:00","chosenRoom": "x","__v": 0},{"_id": "5b09cc6095cb6c0487f1166c","name": "asd","email": "asd#asd.pl","phone": "790467522","kidsNo": "2","adultsNo": "3","fullDate": "2018/5/1","year": "2018","month": "5","day": "1","chosenHour": "12:00","chosenRoom": "x","__v": 0},{"_id": "5b0b1560c7b4fd0c33b2d52e","name": "dddd","email": "dddd#ddd.pl","phone": "123123112","kidsNo": "2","adultsNo": "1","fullDate": "2018/5/17","year": "2018","month": "5","day": "17","chosenHour": "11:00","chosenRoom": "x","__v": 0}],
result = Object.values(array.reduce((a, {day}) => {
let key = `day${day}`;
(a[key] || (a[key] = {[key]: 0}))[key]++;
return a;
}, {}));
console.log(result);
I'm planning on using materialized paths in MongoDB to represent a tree and need to convert the materialized paths back into a JSON tree.
ex.
// Materialized path
var input = [
{"id": "0", "path": "javascript" },
{"id": "1", "path": "javascript/database" },
{"id": "2", "path": "javascript/database/tree" },
{"id": "3", "path": "javascript/mvc" },
{"id": "4", "path": "javascript/mvc/knockout.js"},
{"id": "5", "path": "javascript/mvc/backbone.js"},
{"id": "6", "path": "c++" },
{"id": "7", "path": "c++/c0xx"},
{"id": "8", "path": "c++/c0xx/lambda expressions"},
{"id": "9", "path": "c++/c0xx/vc10" }
];
The result would be:
[
{
"id": "0",
"name": "javascript",
"children": [
{
"id": "1",
"name": "database",
"children": [
{
"id": "2",
"name": "tree",
"children": []
}
]
},
{
"id": "3",
"name": "mvc",
"children": [
{
"id": "4",
"name": "knockout.js",
"children": []
},
{
"id": "5",
"name": "backbone.js",
"children": []
}
]
}
]
},
{
"id": "6",
"name": "c++",
"children": [
{
"id": "7",
"name": "c0xx",
"children": [
{
"id": "8",
"name": "lambda expressions",
"children": []
},
{
"id": "9",
"name": "vc10",
"children": []
}
]
}
]
}
]
I found Convert delimited string into hierarchical JSON with JQuery which works fine.
And I also found Build tree from materialized path which is written in Ruby and uses recursion. I'm interested and curious to see this implemented in Javascript and wonder whether there are any folks that are fluent in both Ruby and Javascript who would like to rewrite it. I did try a Ruby to JS converter, but the result was incomprehensible.
Thanks,
Neville
var Comment = new Schema({
date : {
type : Date,
default : Date.now
},
event: ObjectId,
body : String,
pathComment : String,
user: Array
})
Comment.virtual('level').get(function() {
return this.pathComment.split(',').length;
});
Comment.find({event: event.id}).sort({pathComment:1}).exec(function(err, comment){
var collectComment = function(comment){
return {
body: comment.body,
event: comment.event,
pathComment: comment.pathComment,
id: comment._id,
level: comment.level,
user: comment.user[0],
date: comment.date,
comments: []
};
}
var tplComment = [];
var createChildComment = function(comment, currentNode, level){
if(level==1){
comment.push(collectComment(currentNode));
}else{
createChildComment(comment[comment.length-1]['comments'], currentNode,level-1);
}
return;
}
for(var k in comment){
createChildComment(tplComment, comment[k],comment[k].level);
}
});