This question already has answers here:
javascript | Object grouping
(16 answers)
Closed 4 years ago.
I have an array of objects like this..
[
{
_id: 123
},
{
_id: 123
},
{
_id: 321
}
]
I want to group similar items by _id and also count how many items of each unique _id there are...
[
{
_id: 123
qty: 2
},
{
_id: 321
qty: 1
}
]
Whats the best way to do this using javascript?
You can do this in O(n) time using Array.prototype.reduce() and a Map as the accumulator:
const array = [{'_id':123},{'_id':123},{'_id':321}]
const groups = [...array.reduce(
(map, { _id }) => map.set(_id, (map.get(_id) || 0) + 1),
new Map()
)].map(
([_id, qty]) => ({ _id, qty })
)
console.log(groups)
Related
This question already has answers here:
How to return only value of a field in mongodb
(6 answers)
Closed 3 months ago.
I am using mongodb with mongoose in NodeJs project.
I want to convert my data array of object to array of string like
[
{
id: '6375ce97e8ec382b8dbf8433',
},
{
id: '638de425cbb676123ad204f6',
},
{
id: '638de425cbb676123ad20509',
},
{
id: '6375ce97e8ec382b8dbf8433',
},
{
id: '638dc4cc48b1de03d0d920b7',
},
{
id: '638de425cbb676123ad204f6',
},
{
id: '6375ce97e8ec382b8dbf8433',
},
];
Convert to
['6375ce97e8ec382b8dbf8433',
'638de425cbb676123ad204f6',
'638de425cbb676123ad20509',
'6375ce97e8ec382b8dbf8433',
'638dc4cc48b1de03d0d920b7',
'638de425cbb676123ad204f6',
'6375ce97e8ec382b8dbf8433']
How I convert my data using mongodb not JavaScript method like, map, filter, find etc
I did not convert the data because lack of mongodb knowledge.
You cannot do this directly within mongodb. The reason is that a document must be an object. Eg, you cannot replace the object with a string. Instead, you have 3 options:
1 - Get the output very close, but you just have to locate the array: https://mongoplayground.net/p/furNa_ezJ5l
db.collection.aggregate([
{
$group: {
_id: null,
data: {
$push: "$$ROOT.id"
}
}
}
])
Gives you:
[
{
"_id": null,
"data": [
"6375ce97e8ec382b8dbf8433",
"638de425cbb676123ad204f6",
"638de425cbb676123ad20509",
"6375ce97e8ec382b8dbf8433",
"638dc4cc48b1de03d0d920b7",
"638de425cbb676123ad204f6",
"6375ce97e8ec382b8dbf8433"
]
}
]
Where the data you want will be:
const stringArray = result[0].data
2 - Use JS after your query
db.collection.find({}).toArray().map( function(u) { return u.id } )
3 - Magic distinct values
Assuming that your values of id are always unique and that you don't want to do any further querying or aggregation, you can ask mongo for the unique ones:
db.collection.distinct('id')
Which should give you:
['6375ce97e8ec382b8dbf8433',
'638de425cbb676123ad204f6',
'638de425cbb676123ad20509',
'6375ce97e8ec382b8dbf8433',
'638dc4cc48b1de03d0d920b7',
'638de425cbb676123ad204f6',
'6375ce97e8ec382b8dbf8433']
This question already has answers here:
Filter array of objects based on another array in javascript
(10 answers)
Closed 2 years ago.
i have an array of objects like below,
data: [
{
name: 'name1',
id: '1',
description: 'name 1 description',
},
{
name: 'name2',
id: '2',
description: 'name 2 description',
},
{
name: 'name3',
id: '3',
description: 'name 3 description',
},
]
i have an array consisting of ids like so
const id_list = ['1','2'];
Now i want to retrieve the id and name from data array object whose id matches with id_list
so the expected output is
const new = [
{
id: '1',
name: 'name1',
},
{
id: '2',
name: 'name2',
}
]
i am new to using react, javascript or typescript. could someone help me solve this. thanks.
what i have tried?
i know that to filter the value based on one value
so if i have to filter based on one id say '1'
i can do
const new = data.filter((item) => id === item.id);
but in my case i want to filter all items which match the id_list array and should retrieve only matching object name and id and put it to a array.
You can use the map function with a find method to map every id of id_list to the corresponding object in data
const result = id_list.map((id) => data.find((d) => d.id === id));
After that you have all objects that were found by ids in result. You can either only use the props you want or map again and get only the required properties.
const final = result.map(({ id, name })=> ({ id, name }))
This question already has answers here:
How to determine if Javascript array contains an object with an attribute that equals a given value?
(27 answers)
Closed 3 years ago.
let's say I have an array of objects:
let arr = [
{
name: 'Jack',
id: 1
},
{
name: 'Gabriel',
id: 2
},
{
name: 'John',
id: 3
}
]
I need to check whether that array includes the name 'Jack' for example using:
if (arr.includes('Jack')) {
// don't add name to arr
} else {
// push name into the arr
}
but arr.includes('Jack') returns false, how can I check if an array of objects includes the name?
Since you need to check the object property value in the array, you can try with Array.prototype.some():
The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
let arr = [
{
name: 'Jack',
id: 1
},
{
name: 'Gabriel',
id: 2
},
{
name: 'John',
id: 3
}
]
var r = arr.some(i => i.name.includes('Jack'));
console.log(r);
This question already has answers here:
MongoDB join data inside an array of objects
(2 answers)
Closed 4 years ago.
I have many Shop documents that each contain a field products which is an array of objects where the key is the product ID and the value is the quantity in stock:
{ products: [{"a": 3}, {"b": 27}, {"c": 4}] }
I have a collection Products where each product has a document containing productId, name, etc:
{ productId: "a", "name": "Spanner"}
I would like to pull in/aggregate/join the product information for each of those items. I know how to do it when the field is a single ID, and I have seen this answer which describes how to do it for an array of IDs. But I am having a bit of trouble wrapping my head around what to do with an array of objects containing IDs.
Desired output:
{
products: [
{ {productId: "a", "name": "Spanner"}: 3 }
]
}
(And no, it is not within my control to switch to a relational database.)
I think if you want to using ID for reference, try to avoid place it as object keys, instead make it as object property like { products: [{"productId": $_id, "quantity": 3}]}, that could be a reason for downvote.
But if you cant change it, you can using $objectToArray in aggregation to convert your array.
One more thing, your desire output is unreal because object property in js cant not be an object.
Try it:
db.Shop.aggregate(
// Pipeline
[
// Stage 1
{
$unwind: {
path : "$products"
}
},
// Stage 2
{
$project: {
products: { $objectToArray: "$products" }
}
},
// Stage 3
{
$unwind: {
path : "$products"
}
},
// Stage 4
{
$project: {
productId: "$products.k",
productQuantity: "$products.v"
}
},
// Stage 5
{
$lookup: {
"from" : "products",
"localField" : "productId",
"foreignField" : "productId",
"as" : "products"
}
},
// Stage 6
{
$unwind: {
path : "$products"
}
},
// Stage 7
{
$project: {
productId: "$productId",
productQuantity: "$productQuantity",
productName: "$products.name"
}
},
]);
Good luck
This question already has answers here:
JavaScript merging objects by id [duplicate]
(18 answers)
Closed 6 years ago.
I have an object called probe. It has a property called sensors which is an array.
var probe = {
sensors = [
{ id: 1, checked: false },
{ id: 2, checked: true },
{ id: 3, checked: false },
... //more sensors
],
... //other properties
}
I have separate array which has an updated list of sensors like below.
var updatedSensors = [
{ id: 1, checked: true },
{ id: 3, checked: true }
];
I want to update the sensors array in the probe object from the values in the updatedSensors. How would I do that?
This can be easily achieved by using a couple of for-loops. But for-loops are not the pretty way of iterating in JavaScript, so I was wondering how to do this the preferred way.
Edit:
The objects in the updatedSensors is a subset of objects in probe.sensors. In other words, updatedSensors does not have all the objects (ids) that are there in the probe.sensors, but probe.sensors has all the objects (ids) that are in the updatedSensors.
Thanks.
Try this bit of code:
probe.sensors.map(function (sensor) {
// Loop through updated sensors & match sensor.id so we can reassign val
updatedSensors.map(function (f) {
if (f.id == sensor.id) {
sensor.checked = f.checked
}
})
return sensor;
})