using for loop with push() to create arrays within a new array - node.js

I'm working on a project where I need to declare customsItem formatted in a particular way.
The format given is:
var customsItem = {
"description":"T-Shirt",
"quantity":20,
"net_weight":"1",
"mass_unit":"lb",
"value_amount":"200",
"value_currency":"USD",
"origin_country":"US",
};
In my project however, I have multiple descriptions, so I need to make customsItem an array containing both.
I have array itemInCart =
[
{
itemDescription: 't-shirt',
qty: 1,
pre_orderQty: 1,
price: 30,
weight: 8
},
{
itemDescription: 'pants',
qty: 0,
pre_orderQty: 1,
price: 40,
weight: 5
}
]
I need to get these items in the correct format and within an array called customsItem. I thought to do this using a for loop with push(). Currently, I'm not getting anything when I try to console.log(customsItem), so I'm not sure if this is the best way to achieve the results that I am trying to get. I would really appreciate any help or advice on how to correctly get the results that I need. Thank you!
const customsItem = [];
for (var item of itemInCart) {
const items = {
"description":item.itemDescription,
"quantity":item.qty + item.pre_orderQty,
"net_weight":item.weight,
"mass_unit":"oz",
"value_amount":item.price,
"value_currency":"USD",
"origin_country":"US",
}
customItem.push(
items
)
}

You are not pushing into the correct array:
const customsItem = [];
for (var item of itemInCart) {
const items = {
"description":item.itemDescription,
"quantity":item.qty + item.pre_orderQty,
"net_weight":item.weight,
"mass_unit":"oz",
"value_amount":item.price,
"value_currency":"USD",
"origin_country":"US",
}
customItem.push( <---- needs to be customsItem.push
items
)
}

Related

ForEach Identifiable Struct Object Properties Into List Ordered By categoryName

I feel like I'm missing something obvious here, but I've been stuck on this for a couple of days and just can't seem to find the answer.
1.) I'm using a separate swift file with an Identifiable Struct that has an object with 2 of the Struct properties, name & categoryName. (side note, I'm using var instead of let in the object because the rows can't be rearranged with the .onMove modifier as a constant)
//STRUCT
struct Item: Identifiable {
var id = UUID()
var name: String
var categoryName: String
}
//OBJECT
var items : [Item] = [
//CLOTHING
Item(name: "Hats", categoryName: "Clothing"),
Item(name: "Shirts", categoryName: "Clothing"),
Item(name: "Pants", categoryName: "Clothing"),
//Electronics
Item(name: "Macbook", categoryName: "Electronics"),
Item(name: "Macbook Adapter", categoryName: "Electronics"),
Item(name: "iPhone", categoryName: "Electronics"),
]
2.) In a swiftui file I have this code to build the list, using a nested ForEach loop to pull the categoryName, add it to the Section header, then another to loop out the items.
//List code
NavigationView {
List {
ForEach(items) { currentItem in
Section(header: Text(currentItem.categoryName)){
ForEach(items) { currentItem in
NavigationLink(destination: ItemDetail(itemData: currentItem)){ ItemRow(item: currentItem)
}
}
Unfortunately what I get is a laughable result.
I get my categoryName in the section header and I get my items listed below it. Actually, I get ALL of the items listed below it, regardless of category. Then in a very confusing fashion the sections will print out exactly as many times as the rows in my object array.
In this instance I have 6, so I get 6 rows. Yet, of the 2 categoryName strings "Clothing" and "Electronics", they'll print out 3 times each.
It feels like there's a simple way to do "for each categoryName in items.categoryName add a title to the section and list the corresponding name" - but I'm not cracking this one.
Hoping someone here can point out what I'm doing wrong.
You have flat array and just iterate though it several times, so result is also flat multiplied several times.
Ok, for model you selected, ie items, the result you tried to accomplish can be reached with the following...
List {
ForEach(Array(Set(items.compactMap{ $0[keyPath: \.categoryName] })), id: \.self) { category in
Section(header: Text(category)) {
ForEach(items.filter { $0.categoryName == category }) { currentItem in
NavigationLink(destination: Text("ItemDetail(itemData: currentItem)")){ Text("\(currentItem.name)") }
}
}
}
}
.listStyle(GroupedListStyle())
However I would select different model for items, ie. dictionary as [categoryName: Item]
You can group your array by category:
let sections = Dictionary(grouping: items) { $0.categoryName }
Then you can use it like:
var keys: [String] = { sections.map {$0.key} }
var body: some View {
List {
ForEach(keys, id: \.self) { section in
Section(header: Text(section)){
ForEach(self.sections[section] ?? []) { currentItem in
Text(currentItem.name)
}
}
}
}
}
Note that I have simplified your code to run on my machine but changes are not effecting the answer

NodeJS Iterate through City in JSON, Return Cities and Users in each City

I have the below snippet from a JSON Object that has 3,500 records in it.
[
{
"use:firstName": "Bob",
"use:lastName": "Smith",
"use:categoryId": 36,
"use:company": "BobSmith",
"use:webExId": "Bob.Smith#email.com",
"use:address": {
"com:addressType": "PERSONAL",
"com:city": "US-TX",
"com:country": 1
}
},
{
"use:firstName": "Jane",
"use:lastName": "Doe",
"use:categoryId": 36,
"use:webExId": "Jane.Doe#email.com",
"use:address": {
"com:addressType": "PERSONAL",
"com:city": "US-CA",
"com:country": "1_1"
}
}
{
"use:firstName": "Sam",
"use:lastName": "Sneed",
"use:categoryId": 36,
"use:webExId": "Sam.Sneed#email.com",
"use:address": {
"com:addressType": "PERSONAL",
"com:city": "US-CA",
"com:country": "1_1"
}
}
]
I am using NodeJS and I have been stuck on figuring out the best way to:
1. Iterate through ['use:address']['com:city' to map out and identify all of the Cities. (In the example above, I have two: US-TX and US-CA in the three records provided)
2. Then identify how many records match each City (In the example above, I would have US-TX: 1 and US-CA: 2)
The only code I have is the easy part which is doing a forEach loop through the JSON data, defining userCity variable (to make it easier for me) and then logging to console the results (which is really unnecessary but I did it to confirm I was looping through JSON properly).
function test() {
const webexSiteUserListJson = fs.readFileSync('./src/db/webexSiteUserDetail.json');
const webexSiteUsers = JSON.parse(webexSiteUserListJson);
webexSiteUsers.forEach((userDetails) => {
let userCity = userDetails['use:address']['com:city'];
console.log(userCity);
})
};
I've been searching endlessly for help on the topic and probably not formulating my question properly. Any suggestions are appreciated on how to:
1. Iterate through ['use:address']['com:city' to map out and identify all of the Cities.
2. Then identify how many records match each City (In the example above, I would have US-TX: 1 and US-CA: 2)
Thank you!
You could reduce the webexSiteUsers array into an object that is keyed by city, where each value is the number of times the city occurs. Something like the below should work.
const counts = webexSiteUsers.reduce((countMemo, userDetails) => {
let userCity = userDetails['use:address']['com:city'];
if (countMemo[userCity]) {
countMemo[userCity] = countMemo[userCity] + 1;
} else {
countMemo[userCity] = 1;
}
return countMemo;
}, {});
counts will then be an object that looks like this.
{
"US-TX": 1,
"US-CA": 2
}

array manipulation in node js and lodash

I have two arrays
typeArr = [1010111,23342344]
infoArr={'name':'jon,'age':25}
I am expecting following
[{'name:'jone','age':25,'type':1010111,'default':'ok'},{'name:'jone','age':25,'type':23342344,'default':'nok'}]
Code :
updaterecord(infoArr,type)
{
infoArr.type=type;
response = calculate(age);
if(response)
infoArr.default = 'ok';
else
infoArr.default = 'nok';
return infoArr;
}
createRecord(infoArr,typeArr)
{
var data = _.map(typeArr, type => {
return updaterecord(infoArr,type);
});
return (data);
}
var myData = createRecord(infoArr,typeArr);
I am getting
[{'name:'jone,'age':25.'type':23342344,'default':nok},{'name:'jone,'age':25.'type':23342344,'default':nok}]
with some reason the last record updates the previous one. I have tried generating array using index var but not sure what's wrong it keep overriding the previous item.
how can I resolve this
You are passing the entire infoArr array to your updaterecord() function, but updaterecord() looks like it's expecting a single object. As a result it is adding those properties to the array rather than individual members of the array.
It's not really clear what is supposed to happen because typeArr has two elements and infoArr has one. Do you want to add another to infoArr or should infoArr have the same number of elements as typeArr.
Assuming it should have the same number you would need to use the index the _map gives you to send each item from infoArr:
function createRecord(infoArr,typeArr) {
var data = _.map(typeArr, (type, i) => {
// use infoArr[i] to send one element
return updaterecord(infoArr[i],type);
});
return (data);
}
Edit:
I'm not sure how you are calculating default since it's different in your expected output, but based on one number. To get an array of objects based on infoArray you need to copy the object and add the additional properties the you want. Object.assign() is good for this:
let typeArr = [1010111,23342344]
let infoArr={'name':'jon','age':25}
function updaterecord(infoArr,type){
var obj = Object.assign({}, infoArr)
return Object.assign(obj, {
type: type,
default: infoArr.age > 25 ? 'ok' : 'nok' //or however your figuring this out
})
}
function createRecord(infoArr,typeArr) {
return _.map(typeArr, type => updaterecord(infoArr,type));
}
Result:
[ { name: 'jon', age: 25, type: 1010111, default: 'nok' },
{ name: 'jon', age: 25, type: 23342344, default: 'nok' } ]

Get field value from Array based on another field data matching

Below is my sample JSON object. I want to get the 'title' value based
on the longitude value. I have multiple(20-30) longitudes to get the titles, so I don't want to loop through those many times:
{
items:[
{
longitude:-72.897668,
latitude:40.453576,
title:52 street
},
{
longitude:-71.897668,
latitude:41.453576,
title:5th Ave
}
]
}
Can anyone suggest me how to get value without using for-loops.
Did you try something linke array.filter()?
function filterByLongitude(element) {
var expected = -72.897668
return element.longitude === expected;
}
var items = [{
longitude:-72.897668,
latitude:40.453576,
title:'52 street'
}, {
longitude:-71.897668,
latitude:41.453576,
title: '5th Ave'
}];
var match = items.filter(filterByLongitude);
console.log(match[0].title); // 52 street

Mongoose - Efficient update on an indexed array of mongoose.Schema.Types.Mixed

i have the following simplified Scheme:
var restsSchema = new Schema({
name: String
menu: [mongoose.Schema.Types.Mixed]
});
My document can look like:
{
name: "Sandwiches & More",
menu: [
{id:1,name:"Tona Sandwich",price: 10, soldCounter:0},
{id:2,name:"Salami Sandwich",price: 10, soldCounter:0},
{id:3,name:"Cheese Sandwich",price: 10, soldCounter:0}
]
}
The collection rests is indexed with:
db.rests.createIndex( { "menu.id": 1} , { unique: true })
Lets say i have this array of ids [1,3] and based on that i need to increment the soldCounter by 1 of menu items with ids=1 or 3.
What will be the must efficient way of doing so?
thanks for the helpers!
EDIT:
I have used the following solution:
db.model('rests').update({ _id: restid,'menu.id': {$in: ids}}, {$inc: {'menu.$.soldCounter': 1}}, {multi: true},function(err) {
if(err)
console.log("Error while updating sold counters: " + err.message);
});
where ids is an array of integers with ids of menu items.
restid is the id of the specific document we want to edit in the collection.
For some reason only the first id in the ids array is being updated.
There is a way of doing multiple updates, here it is:
Just make sure you have the indexes in the array you want to update.
var update = { $inc: {} };
for (var i = 0; i < indexes.length; ++i) {
update.$inc[`menu.${indexes[i]}.soldCounter`] = 1;
}
Rests.update({ _id: restid }, update, function(error) {
// ...
});
it seems not possible to update multiple subdocuments at once (see this answer). So a find & save seems to be the only solution.
Rest.findById(restId).then(function(rest){
var menus = rest.menu.filter(function(x){
return menuIds.indexOf(x.id) != -1;
});
for (var menu of menus){
menu.soldCounter++;
}
rest.save();
});
In the end it's only one find and one save requests.

Resources