Nested arrays with objects, lodash meanBy - javascript

Can someone please help me understand how to make this work. Everytime I feel like I start to understand arrays and objects in Javascript it turns out that I still don't.
I'm trying to get the average of all prices in the following datastructure by using lodash meanBy
[
{
date: "2019-12-17",
items: [
{ id: "1", state: "accepted", price: "90.5" },
{ id: "2", state: "rejected", price: "20.0" },
{ id: "3", state: "open", price: "10.5" },
]
},
{
date: "2019-12-18",
items: [
{ id: "4", state: "open", price: "450.0" },
{ id: "5", state: "rejected", price: "40.1" },
{ id: "6", state: "accepted", price: "50.9" },
]
}
]
If you provide the answer, can you also please try to explain how you select something nested in items, because that's as far as I get before I get lost.

In this case instead of selecting nested values, it's easier to flatten the items to a single array, and then apply _.meanBy(). In addition, the prices are strings, and not numbers, so you'll need to convert them.
Flatten the items to a single array with Array.flatMap(), and then use _.meanBy(), and get the numeric values of the prices:
const data = [{"date":"2019-12-17","items":[{"id":"1","state":"accepted","price":"90.5"},{"id":"2","state":"rejected","price":"20.0"},{"id":"3","state":"open","price":"10.5"}]},{"date":"2019-12-18","items":[{"id":"4","state":"open","price":"450.0"},{"id":"5","state":"rejected","price":"40.1"},{"id":"6","state":"accepted","price":"50.9"}]}]
const result = _.meanBy(_.flatMap(data, 'items'), o => +o.price)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Another approach is to get the general average, by getting the average of each items array separately , and then getting the average of all averages.
const data = [{"date":"2019-12-17","items":[{"id":"1","state":"accepted","price":"90.5"},{"id":"2","state":"rejected","price":"20.0"},{"id":"3","state":"open","price":"10.5"}]},{"date":"2019-12-18","items":[{"id":"4","state":"open","price":"450.0"},{"id":"5","state":"rejected","price":"40.1"},{"id":"6","state":"accepted","price":"50.9"}]}]
const result = _.meanBy(data, ({ items }) => _.meanBy(items, o => +o.price))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Related

return charachetrs with the same key door

I have an array of objects(characters) where each object has an array of objects(keys), a door can be opened by multiple keys as you can see in this example
const characters = [
{ id: "1", type: "water", keys: [{ name: "key_786", door: "XOPR" }] },
{ id: "2", type: "fire", keys: [{ name: "key_23", door: "JTHF" }] },
{ id: "3", type: "wind", keys: [{ name: "key_987", door: "XOPR" }] },
];
What I want is to find all the characters that have a key that can open one specific door, for example I want to return all characters with keys.door === 'XOPR' how can I do it ?
I tried .filter .map but no luck, some help please ? I am new to react and javascript
you can use Array.prototype.some with Array.prototype.filter :
const result = characters.filter(ch => ch.keys.some(key => key.door === 'DOOR_NAME'));
First you filter through characters then for every one you loop through its keys property which is an array and for every item of this latter you chack if key.door === 'DOOR_NAME' so you return the character for this itteration(of the filter loop)

Formatting Arrays of Objects into Objects (ES6 Way)

I am trying to create a pretty Objects of arrays but this come instead.
{
"label": [
"Instagram"
],
"value": [
"#username"
]
}
So, how can I change it? What I want is to be like this
{
"label": "instagram",
"value": "#username"
},
I don't know how it happened, but my guess is it was the result of me using formik to define initialValues of a complex nested array from strapi. I was using array.map to map the objects. Hence perhaps thats why it was so messy.
So what is the solution for this? Formatting Arrays of Arrays into Objects? Merging? Converting? I have no idea what it was called. Thanks in advance for anybody replying this.
(updated) The initialValues:
const formik = useFormik({
enableReinitialize: true,
initialValues: {
name: vendor?.name || '',
description: vendor?.description || '',
company: {
social_media: [
{
label: vendor.company?.social_media.map((x) => x.label) || '',
value: vendor.company?.social_media.map((x) => x.value) || ''
}
]
}
},
You can use for..in and array join method
const data = {
"label": [
"Instagram"
],
"value": [
"#username"
]
};
for (let keys in data) {
data[keys] = data[keys].join(',')
};
console.log(data)
Array.map returns an array if you don't want any object use Array.foreach
Or
Use [...Array.map()]
label: [...vendor.company?.social_media.map((x) => x.label)]
value: [...vendor.company?.social_media.map((x) => x.value)

Returning the ids from the object within the arrays

I have a multidimensional javascript array of objects that I am trying to use to simply collate the Unit id into a new array as shown below.
What is the best solution for returning the id within the inner value so I just get an array of the ids whatever I try seems to not work
[
{
units: [
{
id: 10000282,
name: "Group 1",
},
{
id: 10000340,
name: "Group 2",
},
{
id: 10000341,
name: "Group 3",
},
],
},
{
units: [
{
id: 10000334,
name: "Group 4",
},
],
},
]
Expected output - just return an array with simply the ids
e.g
ids = [ 10000282, 10000340, 10000341, 10000334 ]
Assuming that data is in variable data:
> data.map(o => o.units.map(u => u.id)).flat()
[ 10000282, 10000340, 10000341, 10000334 ]
This assumes you're in an environment where .flat() is a thing.
If that's not the case, the longer way around is
const ids = [];
data.forEach(o => {
o.units.forEach(u => {
ids.push(u.id);
});
});

map two 1D arrays into a 2D array and then fill with known values

I', just wondering about the best way to approach this problem. I have two single dimension arrays which I need to merge into a grid, effectively the first array becomes rows and the second array becomes columns - both are of unknown size.
I am thinking nested loops and .push but is there a more elegant solution.
The second part of the problem is slightly trickier. Each of the grid cells will have a key assigned based on the row and column data. I have a third array which contains this key, as a property of the object in the array index and I need to inject (or link) this object to the correct cell in the 2D array. Typically around 80% of the grid will have an associated object in the third array.
The data sets are not huge; the largest grid will only be about 400 cells so an iterative solution will work but it feels dirty. Is there a better 'computer science' method or a javascript array method that will let me achieve what I want.
If not, is there any significant tradeoff between iterating in the items array and trying to find the correct cell in the 2D array or iterating the 2D array to and try to find the matching object in the items array, bearing in mind that I am matching against the item property and not a key.
Sample code below
let arrRow = [
{"code":"S", "desc":"small"},
{"code":"M", "desc":"med"},
{"code":"L", "desc":"large"}
];
let arrCol = [
{"code":"R", "desc":"Red"},
{"code":"G", "desc":"Green"},
{"code":"B", "desc":"Blue"}
];
let arrItems= [
{"item":"SR", "desc":"Small Red"},
{"item":"SB", "desc":"Small Blue"},
{"item":"MB", "desc":"Med Blue"},
{"item":"LB", "desc":"Large Blue"},
{"item":"SG", "desc":"Small Green"},
{"item":"LG", "desc":"Large Green"}
];
As per respondent's request. The desired outcome would be
[
[
{"key":"SR", "value":{"item":"SR", "desc":"Small Red"}},
{"key":"SG", "value":{"item":"SG", "desc":"Small Green"}},
{"key":"SB", "value":{"item":"SB", "desc":"Small Blue"}
],
{"key":"MR", "value":{}},
{"key":"MG", "value":{}},
{"key":"MB", "value":{"item":"MB", "desc":"Med Blue"}}
],
{"key":"LR", "value":{}},
{"key":"LG", "value":{"item":"LG", "desc":"Large Green"}},
{"key":"LB", "value":{"item":"LB", "desc":"Large Blue"}}
]
]
Alternatively the value could just be the index of the element in the item array which is probably more memory efficient
You could take a Map for data and iterate rows and columns.
var arrRow = [{ code: "S", desc: "small" }, { code: "M", desc: "med" }, { code: "L", desc: "large" }],
arrCol = [{ code: "R", desc: "Red" }, { code: "G", desc: "Green" }, { code: "B", desc: "Blue" }],
arrItems = [{ item: "SR", desc: "Small Red" }, { item: "SB", desc: "Small Blue" }, { item: "MB", desc: "Med Blue" }, { item: "LB", desc: "Large Blue" }, { item: "SG", desc: "Small Green" }, { item: "LG", desc: "Large Green" }],
map = arrItems.reduce((m, o) => m.set(o.item, o), new Map),
result = arrRow.map(r => arrCol.map(c => (map.get(r.code + c.code) || {}).desc || ''));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Insert array of objects into MongoDB

I wonder how I could insert array of objects to Mongo collection "root-level documents" with own pre-defined _id values.
I have tried db.MyCollection.insert(array); but it creates nested documents under one single generated _id in MongoDB.
var array = [
{ _id: 'rg8nsoqsxhpNYho2N',
goals: 0,
assists: 1,
total: 1 },
{ _id: 'yKMx6sHQboL5m8Lqx',
goals: 0,
assists: 1,
total: 1 }];
db.MyCollection.insert(array);
What I want
db.collection.insertMany() is what you need (supported from 3.2):
db.users.insertMany(
[
{ name: "bob", age: 42, status: "A", },
{ name: "ahn", age: 22, status: "A", },
{ name: "xi", age: 34, status: "D", }
]
)
output:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("57d6c1d02e9af409e0553dff"),
ObjectId("57d6c1d02323d119e0b3c0e8"),
ObjectId("57d6c1d22323d119e0b3c16c")
]
}
Why not iterate over the array objects, and insert them one at a time?
array.forEach((item) => db.MyCollection.insert(item));
Go through this Link To get Exact Outcome the way you want:
https://docs.mongodb.org/manual/tutorial/insert-documents/#insert-a-document
You can use MongoDB Bulk to insert multiple document in one single call to the database.
First iterate over your array and call the bulk method for each item:
bulk.insert(item)
After the loop, call execute:
bulk.execute()
Take a look at the refereed documentation to learn more.

Categories

Resources