How to add a struct to an array of structs in Go - arrays

In golang I'm trying to make an array of messages, and the ability to easily add a new "object" to the array.
type Message struct {
Name string
Content string
}
var Messages = []Message{
{
Name: "Alice",
Content: "Hello Universe",
},{
Name: "Bob",
Content: "Hello World",
},
}
func addMessage(m string) {
var msg = new(Message)
msg.Name = "Carol"
msg.Content = m
Messages = append(Messages, msg)
}
When building I get an error that says:
cannot use msg (type *Message) as type Message in append
Why is append() not working (as I might expect from JavaScript's array.concat()), or is new() not working?
Any other tips on how to improve this code are welcome since I'm obviously new to Go.

Change these 3 lines
var msg = new(Message)
msg.Name = "Carol"
msg.Content = m
to
msg := Message{
Name: "Carol",
Content: m,
}
and everything should work. new creates a pointer to Message. Your slice is not a slice of Message pointers, but a slice of Messages.

In your code, Messages is a slice of Message type, and you are trying to append a pointer of Message type (*Message) to it.
You can fix your program by doing the following:
func addMessage(m string) {
var msg = new(Message) // return a pointer to msg (type *msg)
msg.Name = "Carol"
msg.Content = m
Messages = append(Messages, *msg) // use the value pointed by msg
}
Alternatively, you can declare Messages as a slice of *Message:
var Messages = []*Message{
&Message{ // Now each entry must be an address to a Message struct
Name: "Alice",
Content: "Hello Universe",
},
&Message{
Name: "Bob",
Content: "Hello World",
},
}
In above case, addMessage wouldn't require any changes. But you'll have to modify Messages access everywhere else.

Related

No exact matches in call to instance method 'append' in swift

Tried to combine or merging two model to one model
1st model = items [ InboxModel]. (My own Inbox)
2nd model = items2 [MoInboxModel] (SDK Inbox)
1st + 2nd -> combinedItems
private var items: [InboxModel] = []
private var items2: [MoInboxModel] = []
private var combinedItems: [combinedInboxModel] = []
struct InboxModel {
let id: String
let title: String
let message: String
let date: Date
}
struct MoInboxModel {
let id: String
let title: String
let message: String
let date: Date
}
struct combinedInboxModel {
let id: String
let title: String
let message: String
let date: Date
}
self?.combinedItems.append(self?.items). //No exact matches in call to instance method 'append
self?.combinedItems.append(contentsOf: self?.items2 ?? []) //No exact matches in call to instance method 'append
Why there is an error while merge it ? How to merge it correctly?
You have three unrelated types - InboxModel, MoInboxModel and combinedInboxModel (Which should be CombinedInboxModel. Even though they all have properties with the same name, they are different types.
There is no append function on an array of combinedInboxModel that accepts an array of InboxModel or MoInboxModel.
You could use map on each of your two input arrays to convert them to an array of CombinedInboxModel which you can then put into combinedItems.
Presumably you are writing this code in a closure, which is why you have a weak self. Best to deal with that first and then process your arrays.
guard let self = self else {
return
}
self.combinedItems = self.items.map { CombinedInboxModel(id:$0.id,title:$0.title,message:$0.message,date:$0.date) }
let items2 = self.items2.map { CombinedInboxModel(id:$0.id,title:$0.title,message:$0.message,date:$0.date) }
self.combinedItems.append(contentsOf:items2)
You haven't shown where items and items2 come from; Is it possible just to fetch them as instances of the same struct to start with?
The fact that you have three structs with the same properties is a bit fishy. I would consider a different design if I were you.
However, if you must go with this approach, you might want to consider starting with a protocol and getting rid of the combinedInboxModel struct.
protocol InboxModelable {
var id: String { get }
var title: String { get }
var message: String { get }
var date: Date { get }
}
Now make your two structs conform to InboxModelable.
struct InboxModel: InboxModelable {
let id: String
let title: String
let message: String
let date: Date
}
struct MoInboxModel: InboxModelable {
let id: String
let title: String
let message: String
let date: Date
}
Since both of your types conform to InboxModelable you can directly store both types in an array of type Array<InboxModelable> without having to map the elements.
class SomeClass {
private var items: [InboxModel] = []
private var items2: [MoInboxModel] = []
private var combinedItems: [InboxModelable] = []
func combineItems() {
doSomething { [weak self] in
guard let self = self else { return }
self.combinedItems.append(contentsOf: self.items)
self.combinedItems.append(contentsOf: self.items2)
}
}
}

args.join is not a function

With my discord bot I am working on a weather command that shows weather on the specified country but when trying to run my command I'm getting this error: TypeError: args.join is not a function Any fix?
My code:
const weather = require('weather-js');
const discord = require('discord.js')
module.exports = {
name: "weather",
description: "Get the weather of anywhere",
category: "info",
usage: "weather <>",
run: ( message, args, client) => {
weather.find({search: args.join(" "), degreeType: 'F'}, function(err, result) {
try {
const embed = new MessageEmbed()
.setTitle(`Weather - ${result[0].location.name}`)
.setColor("#ff2050")
.setDescription("Temperature units can may be differ some time")
.addField("Temperature", `${result[0].current.temperature} Celcius`, true)
.addField("Sky Text", result[0].current.skytext, true)
.addField("Humidity", result[0].current.humidity, true)
.addField("Wind Speed", result[0].current.windspeed, true)
.addField("Observation Time", result[0].current.observationtime, true)
.addField("Wind Display", result[0].current.winddisplay, true)
.setThumbnail(result[0].current.imageUrl);
message.channel.send(embed)
} catch(err) {
return message.channel.send("Unable To Get the data of Given location")
}
});
}
}
I've also tried if (args[0].join... but that doesn't work.
I may be wrong but you have to split the args args.split(" ") before you can join them.
The args returns a string Hello World!
If you were to use args.split(" ") you could do const textSplit = args.split(" ")
It would then return ["Hello", "World!"] as an array
You could THEN use textSplit.join(" ") to add all strings in the array together with with a space.
It would return a string that says "Hello World!"
You could then use textSplit[0] to grab specific text from the array. The 0 position is the word Hello, the 1 position is the word World! and so on. Arrays start from the number 0.
[
"Hello", (0)
"World!" (1)
]
Hope this helps

Newbie: referencing and initializing structure elements within structures

OK, super-newbie Swift learner here with what I am sure is a simple question, that for some reason I cannot wrap my head around.
In the below code, I am creating a (very) simple address book structure just to understand how to reference and initialize the various elements, especially structures within structures. What am I doing wrong and is there a better way to write this? I am getting errors (using Swift Playground).
Errors on the last three lines:
Instance member 'page' cannot be used on the type 'AddressBookStruct'
Instance member 'subscript' cannot be used on type '[AddressPageStruct]'.
Plus, when I set var page = [AddressBookStrcut] I get the error:
Expected member name or constructor call after type name
Thanks in advance for the understanding nudge. :)
struct AddressPageStruct {
let firstName: String
let lastName: String
let cellPhone: Int
init(f: String, l:String, c:Int) {
firstName = f
lastName = l
cellPhone = c
}
}
struct AddressBookStruct {
let color: String
let size: String
var page = [AddressPageStruct]
}
var littleBlackBook = AddressBookStruct.self
littleBlackBook.init(color: "Black", size: "Little")
littleBlackBook.page[0].cellPhone = 6191234567
littleBlackBook.page[0].firstName = "Bob"
littleBlackBook.page[0].lastName = "Smith"
The struct is value type, please check this.
structure vs class in swift language,
you can't make this littleBlackBook.page[0].cellPhone, because cellPhone is constant you use let, instead use the constructor, also I change the page for empty array of AddressPageStruct
import Cocoa
struct AddressPageStruct {
let firstName: String
let lastName: String
let cellPhone: Int
init(f: String, l:String, c:Int) {
firstName = f
lastName = l
cellPhone = c
}
}
struct AddressBookStruct {
let color: String
let size: String
var page = [AddressPageStruct]()
}
var littleBlackBook = AddressBookStruct(color: "Black", size: "Little")
littleBlackBook.page.append(AddressPageStruct(f: "Bob", l: "Smith", c: 6191234567))
print(littleBlackBook.page)
enter code here
var littleBlackBook = AddressBookStruct(color: "Black", size: "Little")
let item = AddressPageStruct(f: "Bob", l: "Smith", c:6191234567 )
littleBlackBook.page.append(item)
littleBlackBook.page.append(AddressPageStruct(f: "Joe", l: "Blog", c: 3123467))
print(littleBlackBook.page[0])
print(littleBlackBook.page[1])
print(littleBlackBook)

Swift: save text field in an array

How to save the text of 2 textfields in an array?
This is what I tried. I use println to check if the values are in the array. But it seems it doesn't work.
Can anyone explain it and please, explain each step. Thank you
1- I create a swift file: novaClass.swift. I create an struct inside
struct novaClass {
var img : String
var text : String
}
2- ViewController.swift Declare an array
var nouArray = [novaClass]()
3- save the text field in the array
#IBAction func save(sender: AnyObject) {
//I put the text of 2 text fields in the array
var nouText = novaClass(img: textField1.text, text: textField2.text)
nouArray.append(nouText)
//I check the array
println(nouArray) // this gives "[_.novaClass]" I do not understand
}
That's the expected behaviour in Swift. Swift objects don't have a description property by default, so println defaults to printing the class name.
Your class can adopt the Printable protocol (which have been renamed to CustomStringConvertible in Swift 2) to provide more detailed printouts:
struct novaClass: Printable {
var img : String
var text : String
var description: String {
get {
return "{img: \(img), text: \(text)}"
}
}
}
Now try it:
var array = [novaClass]()
let x = novaClass(img: "foo", text: "bar")
let y = novaClass(img: "foo2", text: "bar2")
array.append(x)
array.append(y)
println(array) // will print: "[{img: foo, text: bar},{img: foo2, text: bar2}]"
You should check it by
println(nouArray[0].text)
println(nouArray[0].img)
Printing array as object will print its title only

F# - Defining object arrays

I'm trying to create som sample data for a project I'm doing. For that I need a simple object structure where on objects holds an array of objects. In this case a critict that can hold reviews. The code looks like this:
type Review =
{ MovieName: string;
Rating: double }
type Critic =
{ Name: string;
Ratings: Review[] }
let theReviews = [{ MovieName = "First Movie"; Rating = 5.5 }; { MovieName = "Second Movie"; Rating = 7.5 };]
let theCritic = { Name = "The Critic"; Ratings = [{ MovieName = "First Movie"; Rating = 5.5 }; { MovieName = "Second Movie"; Rating = 7.5 };] }
"the reviews" line is working fine but I can't get the "theCritict" line to work. The error I'm getting is:
Error 1 This expression was expected to have type
Review []
but here has type
'a list
How do I get this to work?
Array literals use [| ... |] rather than [ ... ] which are list literals - you need something like
let theCritic = { Name = "The Critic"; Ratings = [|{ MovieName = "First Movie"; Rating = 5.5 }; { MovieName = "Second Movie"; Rating = 7.5 };|] }
This explains the error - you have used a list literal instead of an array literal
actually you're using array in your Review definition and list in the implementation..and these are really different beasts, list are inmutables (better for concurrency) and support pattern matching while arrays are mutables..I recommend you keep using list except for long collections (really longs)
if you wish keep using list you can do it:
type Review =
{ MovieName: string;
Rating: double }
type Critic =
{ Name: string;
Ratings: Review list }
here you've a more detailed list about differences between list and arrays:
http://en.wikibooks.org/wiki/F_Sharp_Programming/Arrays#Differences_Between_Arrays_and_Lists ...

Resources