I have 3 struct data (GOLANG) that I call A, B, and C, struct C is result array replace between struct A and B when data is similar or more than 0 then I set all result to struct C using array.
Struct A, B, C {
TransactionDate string
TotalAmount string
TotalTransaction string
}
A = [
{2019-02-01 0 0}
{2019-02-02 0 0}
{2019-02-03 0 0}
{2019-02-04 0 0}
{2019-02-05 0 0}
{2019-02-06 0 0}
{2019-02-07 0 0}
]
B = [
{2019-02-02 1000 2}
{2019-02-07 200 3}
]
I expect the result is like
C = [
{2019-02-01 0 0}
{2019-02-02 1000 2}
{2019-02-03 0 0}
{2019-02-04 0 0}
{2019-02-05 0 0}
{2019-02-06 0 0}
{2019-02-07 200 3}
]
I try using like this but I can't still like my expected result, can you help me to solve this?
func compareReplace() []C{
var a []A
var b []B
var c []C
for i := 0; i < len(a); i++ {
if a[i].TransactionDate == b[i].TransactionDate {
if b[i].TotalTransaction != "0" {
c = append(c, b[i])
}
}
}
return c
}
Or we can collaborate at https://play.golang.org/p/H-aaolvSDZt
Your logic assumes that the length of a
is always the proper count to conditionally iterate through. The playground that @FatchulAmin shared in a comment on @EdChan answer exposed the issue when a
is larger than b
or vice versa, you will get the "index out of range" error because the smaller slice will no longer have indexes to match the larger. a[i].TransactionDate == b[i].TransactionDate
For sanity, in this case, you should do a check to find the smallest count to iterate with, however, this will not allow you to completely check all of the largest slice.
I suggest merging the slices then finding the largest and smallest to range and loop to remove what you want from the merged. NOTE: @EdChan is right to use one struct since they are all the same.
type FooBar struct {
TransactionDate string
TotalAmount string
TotalTransaction string
}
type FooBarSlice []FooBar // this is used as a receiver on func Remove
func compareReplace(a []FooBar, b []FooBar) []FooBar {
var c FooBarSlice
c = append(a, b...)
var largerSlice []FooBar
var smallerSlice []FooBar
if len(a) <= len(b) {
largerSlice = b
smallerSlice = a
} else {
largerSlice = a
smallerSlice = b
}
for _, v := range smallerSlice {
for j := 0; j < len(largerSlice); j++ {
if largerSlice[j].TransactionDate == v.TransactionDate && largerSlice[j].TotalTransaction == "0" {
c.Remove(j)
}
}
}
return c
}
Full working example: https://play.golang.org/p/iyUYtXlDG54
First of all, I would consider declaring only one struct since the fields of A
, B
and C
is the same. For example:
type FooBar struct {
TransactionDate string
TotalAmount string
TotalTransaction string
}
Then for your function, you can try to rewrite it to:
func compareReplace(a []FooBar, b []FooBar) []FooBar{
var c []foobar
for i := 0; i < len(a); i++ {
if a[i].TransactionDate == b[i].TransactionDate {
if b[i].TotalTransaction != "0" {
c = append(c, b[i])
}
}
}
return c
}
Then at last you might want to fix your logic:
func compareReplace(a []FooBar, b []FooBar) []FooBar{
var c []foobar
for i := 0; i < len(a); i++ {
if a[i].TransactionDate == b[i].TransactionDate {
if b[i].TotalTransaction != "0" {
c = append(c, b[i])
}
} else {
// You might want to append a[i] if the date is mismatching
c = append(c, b[i])
}
}
return c
}