mongodb getting the oldest of animals map/reduce - javascript

I've never tried map/reduce.
How would I get the oldest of each type of animal?
My data is like this:
[
{
"cateory": "animal",
"type": "cat",
"age": 4,
"id": "a"
},
{
"cateory": "animal",
"type": "bird",
"age": 3,
"id": "b"
},
{
"cateory": "animal",
"type": "cat",
"age": 7
"id": "c"
},
{
"cateory": "animal",
"type": "bird",
"age": 4,
"id": "d"
},
{
"cateory": "animal",
"type": "cat",
"age": 8,
"id": "e"
},
{
"cateory": "company",
"type": "Internet",
"age": 5,
"id": "Facebook"
}
]
I'm using node-mongodb-native. Thanks!

Your map function should look something like this:
map = function() {
emit({type: this.type}, {age: this.age});
}
And the reduce function:
reduce = function(key, values) {
maxAge = 0;
values.forEach(function(v) {
if (maxAge < v['age']) {
maxAge = v['age'];
}
});
return {age: maxAge};
}

It's pretty simple:
collection.find({type : 'animal'}).sort({animal: -1}).limit(1);

Related

JS transform deeply nested array of objects at the top level with renaming

I would like to simplify this nested array of objects move some items at the top level with a new property name. Given this data:
let data = [
{
"id": 1001,
"model": "Lemon",
"length": "4",
"details": [
{
"id": 38,
"kind": "D",
"color": "Gray",
"specifics": {
"id": 3
}
}
]
},
{
"id": 1002,
"model": "Botanica",
"length": "2",
"details": [
{
"id": 39,
"kind": "A",
"color": "Yellow",
"specifics": {
"id": 1
}
},
{
"id": 40,
"kind": "B",
"color": "Green",
"specifics": {
"id": 2
}
},
]
}
];
My desired output:
[
{
"id": 3,
"model": "Lemon",
"color": "Gray",
},
{
"id": 1,
"model": "Botanica",
"color": "Yellow",
},
{
"id": 2,
"model": "Botanica",
"color": "Green",
}
]
Or much better to combine the model and color:
[
{
"id": 3,
"model": "Lemon - Gray"
},
{
"id": 1,
"model": "Botanica - Yellow"
},
{
"id": 2,
"model": "Botanica - Green"
}
]
If there are multiple specifics, it would also create a new object together with the model and color, then it would move at the top. Here's what I've tried so far:
const result = data.map(({ details, ...d }) => ({
...d,
data: details.map(({ specifics, ...s }) => ({
...r,
id: specifics.id
}))
}));
But it seems that I can't get the right result. How to simplify this one? Thanks.
First, we need to loop through the data array. We can get the model from the data element namely item. Then we need to loop through that item.details array. From that we can get id, detail.color. Hers's the full code.
let data = [
{
"id": 1001,
"model": "Lemon",
"length": "4",
"details": [
{
"id": 38,
"kind": "D",
"color": "Gray",
"specifics": {
"id": 3
}
}
]
},
{
"id": 1002,
"model": "Botanica",
"length": "2",
"details": [
{
"id": 39,
"kind": "A",
"color": "Yellow",
"specifics": {
"id": 1
}
},
{
"id": 40,
"kind": "B",
"color": "Green",
"specifics": {
"id": 2
}
},
]
}
];
const result = data.reduce((result, item) => {
return [...result, ...item.details.map((detail) => {
return {
id: detail.specifics.id,
model: item.model + " - " + detail.color
}
} )]
}, []);
console.log(result);

Find user details by ID in nested object nodejs | javascript

How to find name using id. means iterate object. create a function const searchName =()=>{}
suppose if pass 3 in function so I'd want to show .... what the name of user like this
const data = [{
"service": [
"BUSINESS",
"LEGAL",
"FINANCE",
"ADVERTISEMENT"
],
"service1": [
{ "id": 1, "name": "a" },
{ "id": 2, "name": "b" },
{ "id": 3, "name": "c" },
{ "id": 4, "name": "d" },
],
"service2": [
{ "id": 5, "name": "e" },
{ "id": 6, "name": "f" },
{ "id": 7, "name": "g" },
{ "id": 8, "name": "h" },
],
"service3": [
{ "id": 9, "name": "i" },
{ "id": 10, "name": "j" },
{ "id": 11, "name": "k" },
{ "id": 12, "name": "l" },
],
"service4": [
{ "id": 13, "name": "m" },
{ "id": 14, "name": "n" },
{ "id": 15, "name": "o" },
{ "id": 16, "name": "p" },
],
}
]
suppose user pass 3 so I want to return { "id": 3, "name": "c" } like this.
I'm trying to iterate this and find the name of the user by id but I didn't understand this iteration so I need your help.
check this code.... Enter any id number
const data = [{
"service": [
"BUSINESS",
"LEGAL",
"FINANCE",
"ADVERTISEMENT"
],
"service1": [
{ "id": 1, "name": "a" },
{ "id": 2, "name": "b" },
{ "id": 3, "name": "c" },
{ "id": 4, "name": "d" },
],
"service2": [
{ "id": 5, "name": "e" },
{ "id": 6, "name": "f" },
{ "id": 7, "name": "g" },
{ "id": 8, "name": "h" },
],
"service3": [
{ "id": 9, "name": "i" },
{ "id": 10, "name": "j" },
{ "id": 11, "name": "k" },
{ "id": 12, "name": "l" },
],
"service4": [
{ "id": 13, "name": "m" },
{ "id": 14, "name": "n" },
{ "id": 15, "name": "o" },
{ "id": 16, "name": "p" },
],
}]
var itemobj = ''
const searchName =(val)=>{
console.log('searchname')
data.map((item)=>{
let obj = Object.keys(item)
obj.map((data)=>{
let inrdata = item[data]
inrdata.map((initem)=>{
let lastdata = initem.id===val?itemobj=initem:null
})
})
})
}
searchName(3)
console.log(itemobj)
function searchName(id) {
let result = null;
for (const [key, value] of Object.entries(data)) {
if (key === "service") continue
result = value.filter(obj => {
return obj.id === id
})
if (result) break
}
return result ? result[0] : null
}
I iterate through keys, I just skip "service" one since it's not revelant.
Then, I filter the "serviceN" array, it will return an array of object (only one if found, empty array if not found).
If it's found, we stop iterating.
Then we return either the first (and logically only element) or null if not found
You could use a combination of flat and find to get get the user by id
function searchName(id) {
return data
.flatMap((item) => Object.values(item))
.flat()
.find((user) => user.id === id);
}
const result = searchName(3); // { id: 3, name: 'c' } | undefined

JSON convert with Javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a json file like as below
[{
"id": 2,
"name": "Ali",
"records":[{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
},{
"id": 3,
"name": "Mete",
"records":[{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}]
I want to convert to like this
[{
"id": 2,
"name": "Ali",
record: {
"type": "L",
"total": 123
}
},{
"id": 2,
"name": "Ali",
record: {
"type": "P",
"total": 102
}
},{
"id": 3,
"name": "Mete",
record: {
"type": "O",
"total": 100
}
},{
"id": 3,
"name": "Mete",
record: {
"type": "T",
"total": 88
}
}]
how can i do it using javascript?
Here is what you could do. However, this doesn't work in IE as is as Object.assign that is being used, isn't yet supported in IE. However, it could be replaced with any javascript object clone methods.
You could check : What is the most efficient way to deep clone an object in JavaScript?
var input = [{
"id": 2,
"name": "Ali",
"records": [{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
}, {
"id": 3,
"name": "Mete",
"records": [{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}];
var output = [];
input.forEach((obj) => {
var records = obj.records;
delete obj.records;
records.forEach((record) => {
// Doesnt have any support in IE.
var newRecord = Object.assign({}, obj);
newRecord.record = record;
output.push(newRecord);
});
});
console.log(output);
If you are fine to use jQuery, here is what you could do.
var input = [{
"id": 2,
"name": "Ali",
"records": [{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
}, {
"id": 3,
"name": "Mete",
"records": [{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}];
var output = [];
input.forEach((obj) => {
var records = obj.records;
delete obj.records;
records.forEach((record) => {
var newRecord = jQuery.extend({}, obj);
newRecord.record = record;
output.push(newRecord);
});
});
console.log(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here's a functional (but probably not very efficient) way of doing it:
function transform(data) {
// Merge the sub arrays together
return [].concat.apply([], (data.map(person => {
// Return an array of copied objects for each person
return person.records.map(record => {
// For each record, copy the person information
return {
id: person.id,
name: person.name,
record: record
};
});
})));
}
console.log(transform([{
"id": 2,
"name": "Ali",
"records":[{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
},{
"id": 3,
"name": "Mete",
"records":[{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}]));
There's a few ways but Array.prototype.map seems to fit the bill. This blurb should get you started:
// We'll assume your original array is called myArray
var newArray = myArray.map ( function ( d ) {
return {
id : (d.id || 'theIDYouWant'),
name : (d.name || 'theNameYouWant' ),
record : { type : d.type, total : d.total }
}
} );
var jsonStr = JSON.stringify ( newArray );
console.log ( jsonStr ); // should write out your JSON as expected.
This will do it and save what you want in new_json
try running the code snippet below
json = [{
"id": 2,
"name": "Ali",
"records": [{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
}, {
"id": 3,
"name": "Mete",
"records": [{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}]
new_json = [];
for (var i = 0; i < json.length; i++) {
for (j = 0; j < json[i]['records'].length; j++) {
new_json.push({
id: json[i]['id'],
name: json[i]['name'],
record: json[i]['records'][j]
})
}
}
console.log(new_json);

Convert object to another object using jQuery

I am getting a result in my JavaScript file which I want to convert into another object.
My original result
[
{
"SName": "Set1",
"Elements": [
{
"Id": "3",
"Name": "Name1"
},
{
"Id": "5",
"Name": "Name2"
}
]
},
{
"SName": "Set2",
"Elements": [
{
"Id": "7",
"Name": "Name3"
},
{
"Id": "8",
"Name": "Name4"
}
]
}
]
Convert this to look like array of objects using jQuery or JavaScript. How can I achieve this?
[
{
"SName": "Set1",
"Id": 3,
"Name": "Name1"
},
{
"SName": "Set1",
"Id": 5,
"Name": "Name2"
},
{
"SName": "Set2",
"Id": 7,
"Name": "Name3"
},
{
"SName": "Set2",
"Id": 8,
"Name": "Name4"
}
]
var data = [
{
"SName": "Set1",
"Elements": [
{
"Id": "3",
"Name": "Name1"
},
{
"Id": "5",
"Name": "Name2"
}
]
},
{
"SName": "Set2",
"Elements": [
{
"Id": "7",
"Name": "Name3"
},
{
"Id": "8",
"Name": "Name4"
}
]
}
];
console.log(data);
var newData = data.reduce(function (newArray, currentSet) {
return newArray.concat(currentSet.Elements.map(function (element) {
return Object.assign( { SName: currentSet.SName }, element);
}));
}, []);
console.log(newData);
The key here is the reduce function. What we are doing is creating a brand new array, by looping through each value of the outer array. We continuously concatenate onto our new array with the values we map from the inner array.
You could iterate the array, the Elements and the properties and build a new object and push it to the result set.
var array = [{ "SName": "Set1", "Elements": [{ "Id": "3", "Name": "Name1" }, { "Id": "5", "Name": "Name2" }] }, { "SName": "Set2", "Elements": [{ "Id": "7", "Name": "Name3" }, { "Id": "8", "Name": "Name4" }] }],
result = [];
array.forEach(function (a) {
a.Elements.forEach(function (b) {
var o = { SName: a.SName };
Object.keys(b).forEach(function (k) {
o[k] = b[k];
});
result.push(o);
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6
var array = [{ "SName": "Set1", "Elements": [{ "Id": "3", "Name": "Name1" }, { "Id": "5", "Name": "Name2" }] }, { "SName": "Set2", "Elements": [{ "Id": "7", "Name": "Name3" }, { "Id": "8", "Name": "Name4" }] }],
result = [];
array.forEach(a => a.Elements.forEach(b => result.push(Object.assign({ SName: a.SName }, b))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this with reduce(), forEach() and Object.assign()
var data = [{
"SName": "Set1",
"Elements": [{
"Id": "3",
"Name": "Name1"
}, {
"Id": "5",
"Name": "Name2"
}]
}, {
"SName": "Set2",
"Elements": [{
"Id": "7",
"Name": "Name3"
}, {
"Id": "8",
"Name": "Name4"
}]
}]
var result = data.reduce(function(r, e) {
e.Elements.forEach(function(o) {
r.push(Object.assign({SName: e.SName}, o))
})
return r;
}, [])
console.log(result)
Here is solution using jQuery, here is jsfiddle:
https://jsfiddle.net/noitse/3uk9qjnf/
I hope you know all key names so it wont be problem to do it fixed.
var json = [
{
"SName": "Set1",
"Elements": [
{
"Id": "3",
"Name": "Name1"
},
{
"Id": "5",
"Name": "Name2"
}
]
},
{
"SName": "Set2",
"Elements": [
{
"Id": "7",
"Name": "Name3"
},
{
"Id": "8",
"Name": "Name4"
}
]
}
]
var newJSON = []
$(json).each(function(index,value){
$(value.Elements).each(function(index1,value1){
newJSON.push({"SName":value.SName,"Id":value1.Id,"Name":value1.Name})
})
})
alert(JSON.stringify(newJSON))
Here is code , what it does it loops through first JSON , then loops through its elements , then it push it to new array
You could use the $.extend method, which lets you create a copy of an object, while merging with another object.
var source = [] // Replace with the initalization of your source array
var destination = [];
for (var i = 0; i < source.length; i++) {
var node = source[i];
for (var j = 0; j < node.Elements.length; j++) {
var subNode = node.Elements[j];
newNode = $.extend(subNode, node);
delete newNode["Elements"];
destination.push(newNode);
}
}
You can run the code in this fiddle.

Merge two objects when there's a new key

I have two objects with the following structure and tried to merge them together.
I tried it with $.merge but its not the expected result.
Object 1 - Has not all attributes
{
"id": 23,
"name": "Article",
"related": 15 "items": [{
"name": "Test1",
"items": [{
"name": "Test2",
"items": [{
"name": "Test3",
"items": [{
"name": "Test4",
"items": [{
"name": "Test5",
"items": [{
"name": "Test6",
}]
}]
}]
}]
}]
}]
}, {
"id": 24…
}
Object 2 - with additional attributes
{
"id": 23,
"name": "Article",
"related": 15 "items": [{
"name": "Test1",
"id": 34 "items": [{
"name": "Test2",
"id": 57 "items": [{
"name": "Test3",
"id": 92 "items": [{
"name": "THIS ONE IS NOT EXISTING IN OBJECT 1 AND SHOULD NOT GET MERGED",
"id": 789
}, {
"name": "Test4",
"id": 12 "items": [{
"name": "Test5",
"id": 321 "items": [{
"name": "Test6",
"id": 285
}]
}]
}]
}]
}]
}]
}, {
"id": 24…
}
Does anyone know some smart trick? Is jQuery even necessary?
jQuery's $.extend will do what you want.
//merging two objects into new object
var new_object = $.extend(true, {}, object1, object2);
//merge object2 into object1
$.extend(true, object1, object2);
The 1st parameter: deep:true, see: https://api.jquery.com/jquery.extend/
Without jquery: https://jsfiddle.net/sLhcbewh/
function mymerge_sub(object1, object2)
{
for(var i in object2) {
if(i == 'items')
continue;
console.log(i);
if(object1[i] === undefined) {
console.log(i + ' not found');
object1[i] = object2[i];
}
}
if(object1.items !== undefined) {
mymerge_sub(object1.items[0], object2.items[0])
}
}
function mymerge(object1, object2) {
var ret = JSON.parse(JSON.stringify(object1));
mymerge_sub(ret, object2); // save obj 1
return ret;
}
var obj3 = mymerge(obj1, obj2);
If you want several items, you have to loop mymerge_sub(object1.items[j]... ).

Categories