如何根据空字段筛选JSON数据?

huangapple go评论134阅读模式
英文:

How to filter JSON data based off an empty field?

问题

我正在调用一个API,并尝试解析返回的数据以过滤出所需的数据。我创建了一个条件循环,用于遍历每个对象并检查字段Relationships.CurrentConfigurationVersion.Data是否为空。

以下是我的第一次尝试:

  1. func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
  2. // 省略了API调用以简洁起见
  3. // body保存JSON响应
  4. body, err := ioutil.ReadAll(resp.Body)
  5. // 将结构体类型标记为data
  6. var data WorkspacesJSON
  7. err = json.Unmarshal(body, data)
  8. if err != nil {
  9. panic(err)
  10. }
  11. var data2 []*WorkspacesJSON
  12. for _, v := range data.Data {
  13. if v.Relationships.CurrentConfigurationVersion.Data == " " {
  14. data2 = append(data2, v)
  15. }
  16. }
  17. }

错误发生在条件语句中,因为我将一个结构体类型与一个字符串进行比较。

无法将""(无类型字符串常量)转换为struct{ID string "json:"id""; Type string "json:"type""}


第二次尝试
在搜索了一些信息后,我尝试了另一种方法:

  1. func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
  2. // 省略了API调用以简洁起见
  3. // body保存JSON响应
  4. body, err := ioutil.ReadAll(resp.Body)
  5. // 将结构体类型标记为data,这次附加了[]*
  6. var data []*WorkspacesJSON
  7. // 在这次尝试中添加了&
  8. err = json.Unmarshal(body, &data)
  9. if err != nil {
  10. panic(err)
  11. }
  12. var data2 []*WorkspacesJSON
  13. for _, v := range data.Data {
  14. if v.Relationships.CurrentConfigurationVersion.Data == " " {
  15. data2 = append(data2, v)
  16. }
  17. }
  18. }

编译器报告了另一个错误,但这次是针对v.Relationships.CurrentConfigurationVersion.Data,错误信息是:

v.Relationships未定义(*WorkspacesJSON类型没有字段或方法Relationships)compilerMissingFieldOrMethod
我不确定为什么会出现这个错误,因为在我的第一次尝试中没有这个问题?显然我对此不太理解。

这是我的type struct
它相当长,但唯一重要的字段是Data.Relationships.CurrentConfigurationVersion.Data

  1. type WorkspacesJSON struct {
  2. Data []struct {
  3. ID string `json:"id"`
  4. Type string `json:"type"`
  5. Attributes struct {
  6. AllowDestroyPlan bool `json:"allow-destroy-plan"`
  7. AutoApply bool `json:"auto-apply"`
  8. AutoDestroyAt interface{} `json:"auto-destroy-at"`
  9. CreatedAt time.Time `json:"created-at"`
  10. Environment string `json:"environment"`
  11. Locked bool `json:"locked"`
  12. Name string `json:"name"`
  13. QueueAllRuns bool `json:"queue-all-runs"`
  14. SpeculativeEnabled bool `json:"speculative-enabled"`
  15. StructuredRunOutputEnabled bool `json:"structured-run-output-enabled"`
  16. TerraformVersion string `json:"terraform-version"`
  17. WorkingDirectory string `json:"working-directory"`
  18. GlobalRemoteState bool `json:"global-remote-state"`
  19. UpdatedAt time.Time `json:"updated-at"`
  20. ResourceCount int `json:"resource-count"`
  21. ApplyDurationAverage int `json:"apply-duration-average"`
  22. PlanDurationAverage int `json:"plan-duration-average"`
  23. PolicyCheckFailures int `json:"policy-check-failures"`
  24. RunFailures int `json:"run-failures"`
  25. WorkspaceKpisRunsCount int `json:"workspace-kpis-runs-count"`
  26. LatestChangeAt time.Time `json:"latest-change-at"`
  27. Operations bool `json:"operations"`
  28. ExecutionMode string `json:"execution-mode"`
  29. VcsRepo struct {
  30. Branch string `json:"branch"`
  31. IngressSubmodules bool `json:"ingress-submodules"`
  32. Identifier string `json:"identifier"`
  33. DisplayIdentifier string `json:"display-identifier"`
  34. OauthTokenID string `json:"oauth-token-id"`
  35. WebhookURL string `json:"webhook-url"`
  36. RepositoryHTTPURL string `json:"repository-http-url"`
  37. ServiceProvider string `json:"service-provider"`
  38. } `json:"vcs-repo"`
  39. VcsRepoIdentifier string `json:"vcs-repo-identifier"`
  40. Permissions struct {
  41. CanUpdate bool `json:"can-update"`
  42. CanDestroy bool `json:"can-destroy"`
  43. CanQueueDestroy bool `json:"can-queue-destroy"`
  44. CanQueueRun bool `json:"can-queue-run"`
  45. CanQueueApply bool `json:"can-queue-apply"`
  46. CanReadStateVersions bool `json:"can-read-state-versions"`
  47. CanCreateStateVersions bool `json:"can-create-state-versions"`
  48. CanReadVariable bool `json:"can-read-variable"`
  49. CanUpdateVariable bool `json:"can-update-variable"`
  50. CanLock bool `json:"can-lock"`
  51. CanUnlock bool `json:"can-unlock"`
  52. CanForceUnlock bool `json:"can-force-unlock"`
  53. CanReadSettings bool `json:"can-read-settings"`
  54. CanManageTags bool `json:"can-manage-tags"`
  55. } `json:"permissions"`
  56. Actions struct {
  57. IsDestroyable bool `json:"is-destroyable"`
  58. } `json:"actions"`
  59. Description interface{} `json:"description"`
  60. FileTriggersEnabled bool `json:"file-triggers-enabled"`
  61. TriggerPrefixes []interface{} `json:"trigger-prefixes"`
  62. Source string `json:"source"`
  63. SourceName interface{} `json:"source-name"`
  64. SourceURL interface{} `json:"source-url"`
  65. TagNames []interface{} `json:"tag-names"`
  66. } `json:"attributes"`
  67. Relationships struct {
  68. Organization struct {
  69. Data struct {
  70. ID string `json:"id"`
  71. Type string `json:"type"`
  72. } `json:"data"`
  73. } `json:"organization"`
  74. CurrentRun struct {
  75. Data struct {
  76. ID string `json:"id"`
  77. Type string `json:"type"`
  78. } `json:"data"`
  79. Links struct {
  80. Related string `json:"related"`
  81. } `json:"links"`
  82. } `json:"current-run"`
  83. LatestRun struct {
  84. Data struct {
  85. ID string `json:"id"`
  86. Type string `json:"type"`
  87. } `json:"data"`
  88. Links struct {
  89. Related string `json:"related"`
  90. } `json:"links"`
  91. } `json:"latest-run"`
  92. Outputs struct {
  93. Data []interface{} `json:"data"`
  94. } `json:"outputs"`
  95. RemoteStateConsumers struct {
  96. Links struct {
  97. Related string `json:"related"`
  98. } `json:"links"`
  99. } `json:"remote-state-consumers"`
  100. CurrentStateVersion struct {
  101. Data struct {
  102. ID string `json:"id"`
  103. Type string `json:"type"`
  104. } `json:"data"`
  105. Links struct {
  106. Related string `json:"related"`
  107. } `json:"links"`
  108. } `json:"current-state-version"`
  109. CurrentConfigurationVersion struct {
  110. Data struct {
  111. ID string `json:"id"`
  112. Type string `json:"type"`
  113. } `json:"data"`
  114. Links struct {
  115. Related string `json:"related"`
  116. } `json:"links"`
  117. } `json:"current-configuration-version"`
  118. AgentPool struct {
  119. Data interface{} `json:"data"`
  120. } `json:"agent-pool"`
  121. Readme struct {
  122. Data struct {
  123. ID string `json:"id"`
  124. Type string `json:"type"`
  125. } `json:"data"`
  126. } `json:"readme"`
  127. } `json:"relationships"`
  128. Links struct {
  129. Self string `json:"self"`
  130. } `json:"links"`
  131. } `json:"data"`
  132. Links struct {
  133. Self string `json:"self"`
  134. First string `json:"first"`
  135. Prev interface{} `json:"prev"`
  136. Next string `json:"next"`
  137. Last string `json:"last"`
  138. } `json:"links"`
  139. Meta struct {
  140. StatusCounts struct {
  141. Pending int `json:"pending"`
  142. PlanQueued int `json:"plan-queued"`
  143. Planning int `json:"planning"`
  144. Planned int `json:"planned"`
  145. Confirmed int `json:"confirmed"`
  146. ApplyQueued int `json:"apply-queued"`
  147. Applying int `json:"applying"`
  148. Applied int `json:"applied"`
  149. Discarded int `json:"discarded"`
  150. Errored int `json:"errored"`
  151. Canceled int `json:"canceled"`
  152. CostEstimating int `json:"cost-estimating"`
  153. CostEstimated int `json:"cost-estimated"`
  154. PolicyChecking int `json:"policy-checking"`
  155. PolicyOverride int `json:"policy-override"`
  156. PolicyChecked int `json:"policy-checked"`
  157. PolicySoftFailed int `json:"policy-soft-failed"`
  158. PlannedAndFinished int `json:"planned-and-finished"`
  159. PostPlanRunning int `json:"post-plan-running"`
  160. PostPlanCompleted int `json:"post-plan-completed"`
  161. PreApplyRunning int `json:"pre-apply-running"`
  162. PreApplyCompleted int `json:"pre-apply-completed"`
  163. Fetching int `json:"fetching"`
  164. None int `json:"none"`
  165. Total int `json:"total"`
  166. } `json:"status-counts"`
  167. Pagination struct {
  168. CurrentPage int `json:"current-page"`
  169. PageSize int `json:"page-size"`
  170. PrevPage interface{} `json:"prev-page"`
  171. NextPage int `json:"next-page"`
  172. TotalPages int `json:"total-pages"`
  173. TotalCount int `json:"total-count"`
  174. } `json:"pagination"`
  175. } `json:"meta"`
  176. }

我陷入了这两个相同错误的无限循环中,并试图创建一些hacky函数来完成工作,但没有成功。

我对Go非常陌生,我有使用Python并在Py中处理JSON更容易,但我想尝试使用Go。提前感谢您的指导。

如何使用条件语句过滤我的JSON body,以检查字段是否为空?

编辑:
在我的第二次尝试中,我如何选择我要查找的字段Relationships.CurrentConfigurationVersion.Data?一旦我弄清楚了这一点,我想我就可以解决问题了。目前它说WorkspaceJSON没有Relationships字段或方法。这在我的第一次尝试中不是这样的。

英文:

I'm calling an API and trying to parse the body response to filter out data. I've created a conditional for-loop to go through each object and check whether this field: Relationships.CurrentConfigurationVersion.Data is empty.

Here is my first attempt:

  1. func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
  2. // omitted API calls for brevity
  3. // body holds the JSON response
  4. body, err := ioutil.ReadAll(resp.Body)
  5. // label my struct type as data
  6. var data WorkspacesJSON
  7. err = json.Unmarshal(body, data)
  8. if err != nil {
  9. panic(err)
  10. }
  11. var data2 []*WorkspacesJSON
  12. for _, v := range data.Data {
  13. if v.Relationships.CurrentConfigurationVersion.Data == " " {
  14. data2 = append(data2, v)
  15. }
  16. }
  17. }

The error occurs in the conditional statement because I'm comparing a struct type to a string.

>cannot convert "" (untyped string constant) to struct{ID string "json:"id""; Type string "json:"type""}


Attempt 2
After some searching around I tried another attempt from information I learned:

  1. func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
  2. // omitted API calls for brevity
  3. // body holds the JSON response
  4. body, err := ioutil.ReadAll(resp.Body)
  5. // label my struct type as data, this time attach []*
  6. var data []*WorkspacesJSON
  7. // added & in this new attempt
  8. err = json.Unmarshal(body, &data)
  9. if err != nil {
  10. panic(err)
  11. }
  12. var data2 []*WorkspacesJSON
  13. for _, v := range data.Data {
  14. if v.Relationships.CurrentConfigurationVersion.Data == " " {
  15. data2 = append(data2, v)
  16. }
  17. }
  18. }

The compiler throw another error but this time targeting v.Relationships.CurrentConfigurationVersion.Data saying:
>v.Relationships undefined (type *WorkspacesJSON has no field or method Relationships)compilerMissingFieldOrMethod
I'm not sure why I'm getting this error because in my first attempt this was not a problem? Clearly I am not understanding this.

Here is my type struct:
It's fairly long but the only field of important is Data.Relationships.CurrentConfigurationVersion.Data

  1. type WorkspacesJSON struct {
  2. Data []struct {
  3. ID string `json:"id"`
  4. Type string `json:"type"`
  5. Attributes struct {
  6. AllowDestroyPlan bool `json:"allow-destroy-plan"`
  7. AutoApply bool `json:"auto-apply"`
  8. AutoDestroyAt interface{} `json:"auto-destroy-at"`
  9. CreatedAt time.Time `json:"created-at"`
  10. Environment string `json:"environment"`
  11. Locked bool `json:"locked"`
  12. Name string `json:"name"`
  13. QueueAllRuns bool `json:"queue-all-runs"`
  14. SpeculativeEnabled bool `json:"speculative-enabled"`
  15. StructuredRunOutputEnabled bool `json:"structured-run-output-enabled"`
  16. TerraformVersion string `json:"terraform-version"`
  17. WorkingDirectory string `json:"working-directory"`
  18. GlobalRemoteState bool `json:"global-remote-state"`
  19. UpdatedAt time.Time `json:"updated-at"`
  20. ResourceCount int `json:"resource-count"`
  21. ApplyDurationAverage int `json:"apply-duration-average"`
  22. PlanDurationAverage int `json:"plan-duration-average"`
  23. PolicyCheckFailures int `json:"policy-check-failures"`
  24. RunFailures int `json:"run-failures"`
  25. WorkspaceKpisRunsCount int `json:"workspace-kpis-runs-count"`
  26. LatestChangeAt time.Time `json:"latest-change-at"`
  27. Operations bool `json:"operations"`
  28. ExecutionMode string `json:"execution-mode"`
  29. VcsRepo struct {
  30. Branch string `json:"branch"`
  31. IngressSubmodules bool `json:"ingress-submodules"`
  32. Identifier string `json:"identifier"`
  33. DisplayIdentifier string `json:"display-identifier"`
  34. OauthTokenID string `json:"oauth-token-id"`
  35. WebhookURL string `json:"webhook-url"`
  36. RepositoryHTTPURL string `json:"repository-http-url"`
  37. ServiceProvider string `json:"service-provider"`
  38. } `json:"vcs-repo"`
  39. VcsRepoIdentifier string `json:"vcs-repo-identifier"`
  40. Permissions struct {
  41. CanUpdate bool `json:"can-update"`
  42. CanDestroy bool `json:"can-destroy"`
  43. CanQueueDestroy bool `json:"can-queue-destroy"`
  44. CanQueueRun bool `json:"can-queue-run"`
  45. CanQueueApply bool `json:"can-queue-apply"`
  46. CanReadStateVersions bool `json:"can-read-state-versions"`
  47. CanCreateStateVersions bool `json:"can-create-state-versions"`
  48. CanReadVariable bool `json:"can-read-variable"`
  49. CanUpdateVariable bool `json:"can-update-variable"`
  50. CanLock bool `json:"can-lock"`
  51. CanUnlock bool `json:"can-unlock"`
  52. CanForceUnlock bool `json:"can-force-unlock"`
  53. CanReadSettings bool `json:"can-read-settings"`
  54. CanManageTags bool `json:"can-manage-tags"`
  55. } `json:"permissions"`
  56. Actions struct {
  57. IsDestroyable bool `json:"is-destroyable"`
  58. } `json:"actions"`
  59. Description interface{} `json:"description"`
  60. FileTriggersEnabled bool `json:"file-triggers-enabled"`
  61. TriggerPrefixes []interface{} `json:"trigger-prefixes"`
  62. Source string `json:"source"`
  63. SourceName interface{} `json:"source-name"`
  64. SourceURL interface{} `json:"source-url"`
  65. TagNames []interface{} `json:"tag-names"`
  66. } `json:"attributes"`
  67. Relationships struct {
  68. Organization struct {
  69. Data struct {
  70. ID string `json:"id"`
  71. Type string `json:"type"`
  72. } `json:"data"`
  73. } `json:"organization"`
  74. CurrentRun struct {
  75. Data struct {
  76. ID string `json:"id"`
  77. Type string `json:"type"`
  78. } `json:"data"`
  79. Links struct {
  80. Related string `json:"related"`
  81. } `json:"links"`
  82. } `json:"current-run"`
  83. LatestRun struct {
  84. Data struct {
  85. ID string `json:"id"`
  86. Type string `json:"type"`
  87. } `json:"data"`
  88. Links struct {
  89. Related string `json:"related"`
  90. } `json:"links"`
  91. } `json:"latest-run"`
  92. Outputs struct {
  93. Data []interface{} `json:"data"`
  94. } `json:"outputs"`
  95. RemoteStateConsumers struct {
  96. Links struct {
  97. Related string `json:"related"`
  98. } `json:"links"`
  99. } `json:"remote-state-consumers"`
  100. CurrentStateVersion struct {
  101. Data struct {
  102. ID string `json:"id"`
  103. Type string `json:"type"`
  104. } `json:"data"`
  105. Links struct {
  106. Related string `json:"related"`
  107. } `json:"links"`
  108. } `json:"current-state-version"`
  109. CurrentConfigurationVersion struct {
  110. Data struct {
  111. ID string `json:"id"`
  112. Type string `json:"type"`
  113. } `json:"data"`
  114. Links struct {
  115. Related string `json:"related"`
  116. } `json:"links"`
  117. } `json:"current-configuration-version"`
  118. AgentPool struct {
  119. Data interface{} `json:"data"`
  120. } `json:"agent-pool"`
  121. Readme struct {
  122. Data struct {
  123. ID string `json:"id"`
  124. Type string `json:"type"`
  125. } `json:"data"`
  126. } `json:"readme"`
  127. } `json:"relationships"`
  128. Links struct {
  129. Self string `json:"self"`
  130. } `json:"links"`
  131. } `json:"data"`
  132. Links struct {
  133. Self string `json:"self"`
  134. First string `json:"first"`
  135. Prev interface{} `json:"prev"`
  136. Next string `json:"next"`
  137. Last string `json:"last"`
  138. } `json:"links"`
  139. Meta struct {
  140. StatusCounts struct {
  141. Pending int `json:"pending"`
  142. PlanQueued int `json:"plan-queued"`
  143. Planning int `json:"planning"`
  144. Planned int `json:"planned"`
  145. Confirmed int `json:"confirmed"`
  146. ApplyQueued int `json:"apply-queued"`
  147. Applying int `json:"applying"`
  148. Applied int `json:"applied"`
  149. Discarded int `json:"discarded"`
  150. Errored int `json:"errored"`
  151. Canceled int `json:"canceled"`
  152. CostEstimating int `json:"cost-estimating"`
  153. CostEstimated int `json:"cost-estimated"`
  154. PolicyChecking int `json:"policy-checking"`
  155. PolicyOverride int `json:"policy-override"`
  156. PolicyChecked int `json:"policy-checked"`
  157. PolicySoftFailed int `json:"policy-soft-failed"`
  158. PlannedAndFinished int `json:"planned-and-finished"`
  159. PostPlanRunning int `json:"post-plan-running"`
  160. PostPlanCompleted int `json:"post-plan-completed"`
  161. PreApplyRunning int `json:"pre-apply-running"`
  162. PreApplyCompleted int `json:"pre-apply-completed"`
  163. Fetching int `json:"fetching"`
  164. None int `json:"none"`
  165. Total int `json:"total"`
  166. } `json:"status-counts"`
  167. Pagination struct {
  168. CurrentPage int `json:"current-page"`
  169. PageSize int `json:"page-size"`
  170. PrevPage interface{} `json:"prev-page"`
  171. NextPage int `json:"next-page"`
  172. TotalPages int `json:"total-pages"`
  173. TotalCount int `json:"total-count"`
  174. } `json:"pagination"`
  175. } `json:"meta"`
  176. }

I'm stuck in an eternal loop of those two same errors above, and trying to create hacky functions to get the job done, but no luck.

I'm very new to Go, I have experience with Python and working with JSON in Py is much easier for me but I want to try this using Go. Thanks in advance for your guidance.

How can I filter my JSON body using a conditional to check if a field is empty?

EDIT:
In my second attempt, How would I be able to select the field I'm looking for, Relationships.CurrentConfigurationVersion.Data? Once I figure that out I think I will be okay. Currently its saying that WorkspaceJSON has no field of method forRelationships. This was not the case for my first attempt.

答案1

得分: 1

有很多方法可以检查struct是否为空,可以在这里讨论:https://stackoverflow.com/questions/28447297/how-to-check-for-an-empty-struct/70963709

此外,代码中的append部分必须具有相同的类型,如下所示:

  1. data2 := WorkspacesJSON{}
  2. for _, v := range data.Data {
  3. if fmt.Sprintf("%v", v.Relationships.CurrentConfigurationVersion.Data) == "{}" {
  4. data2.Data = append(data2.Data, v)
  5. }
  6. }
英文:

There are lots of ways to check is struct empty or not, which is discussed here: https://stackoverflow.com/questions/28447297/how-to-check-for-an-empty-struct/70963709

Also the append part of the code, must have the same type; as the following code:

  1. data2 := WorkspacesJSON{}
  2. for _, v := range data.Data {
  3. if fmt.Sprintf("%v", v.Relationships.CurrentConfigurationVersion.Data) == "{ }" {
  4. data2.Data = append(data2.Data, v)
  5. }
  6. }

huangapple
  • 本文由 发表于 2022年2月3日 03:57:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/70962091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定