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

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

How to filter JSON data based off an empty field?

问题

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

以下是我的第一次尝试:

func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
    
    // 省略了API调用以简洁起见

    // body保存JSON响应
	body, err := ioutil.ReadAll(resp.Body)

    // 将结构体类型标记为data
	var data WorkspacesJSON

	err = json.Unmarshal(body, data)
	if err != nil {
		panic(err)
	}

	var data2 []*WorkspacesJSON
	for _, v := range data.Data {
		if v.Relationships.CurrentConfigurationVersion.Data == " " {
			data2 = append(data2, v)
		}
	}
}

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

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


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

func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
    
    // 省略了API调用以简洁起见

    // body保存JSON响应
	body, err := ioutil.ReadAll(resp.Body)

    // 将结构体类型标记为data,这次附加了[]*
	var data []*WorkspacesJSON

    // 在这次尝试中添加了&
	err = json.Unmarshal(body, &data)
	if err != nil {
		panic(err)
	}

	var data2 []*WorkspacesJSON
	for _, v := range data.Data {
		if v.Relationships.CurrentConfigurationVersion.Data == " " {
			data2 = append(data2, v)
		}
	}
}

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

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

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

type WorkspacesJSON struct {
    Data []struct {
        ID         string `json:"id"`
        Type       string `json:"type"`
        Attributes struct {
            AllowDestroyPlan           bool        `json:"allow-destroy-plan"`
            AutoApply                  bool        `json:"auto-apply"`
            AutoDestroyAt              interface{} `json:"auto-destroy-at"`
            CreatedAt                  time.Time   `json:"created-at"`
            Environment                string      `json:"environment"`
            Locked                     bool        `json:"locked"`
            Name                       string      `json:"name"`
            QueueAllRuns               bool        `json:"queue-all-runs"`
            SpeculativeEnabled         bool        `json:"speculative-enabled"`
            StructuredRunOutputEnabled bool        `json:"structured-run-output-enabled"`
            TerraformVersion           string      `json:"terraform-version"`
            WorkingDirectory           string      `json:"working-directory"`
            GlobalRemoteState          bool        `json:"global-remote-state"`
            UpdatedAt                  time.Time   `json:"updated-at"`
            ResourceCount              int         `json:"resource-count"`
            ApplyDurationAverage       int         `json:"apply-duration-average"`
            PlanDurationAverage        int         `json:"plan-duration-average"`
            PolicyCheckFailures        int         `json:"policy-check-failures"`
            RunFailures                int         `json:"run-failures"`
            WorkspaceKpisRunsCount     int         `json:"workspace-kpis-runs-count"`
            LatestChangeAt             time.Time   `json:"latest-change-at"`
            Operations                 bool        `json:"operations"`
            ExecutionMode              string      `json:"execution-mode"`
            VcsRepo                    struct {
                Branch            string `json:"branch"`
                IngressSubmodules bool   `json:"ingress-submodules"`
                Identifier        string `json:"identifier"`
                DisplayIdentifier string `json:"display-identifier"`
                OauthTokenID      string `json:"oauth-token-id"`
                WebhookURL        string `json:"webhook-url"`
                RepositoryHTTPURL string `json:"repository-http-url"`
                ServiceProvider   string `json:"service-provider"`
            } `json:"vcs-repo"`
            VcsRepoIdentifier string `json:"vcs-repo-identifier"`
            Permissions       struct {
                CanUpdate              bool `json:"can-update"`
                CanDestroy             bool `json:"can-destroy"`
                CanQueueDestroy        bool `json:"can-queue-destroy"`
                CanQueueRun            bool `json:"can-queue-run"`
                CanQueueApply          bool `json:"can-queue-apply"`
                CanReadStateVersions   bool `json:"can-read-state-versions"`
                CanCreateStateVersions bool `json:"can-create-state-versions"`
                CanReadVariable        bool `json:"can-read-variable"`
                CanUpdateVariable      bool `json:"can-update-variable"`
                CanLock                bool `json:"can-lock"`
                CanUnlock              bool `json:"can-unlock"`
                CanForceUnlock         bool `json:"can-force-unlock"`
                CanReadSettings        bool `json:"can-read-settings"`
                CanManageTags          bool `json:"can-manage-tags"`
            } `json:"permissions"`
            Actions struct {
                IsDestroyable bool `json:"is-destroyable"`
            } `json:"actions"`
            Description         interface{}   `json:"description"`
            FileTriggersEnabled bool          `json:"file-triggers-enabled"`
            TriggerPrefixes     []interface{} `json:"trigger-prefixes"`
            Source              string        `json:"source"`
            SourceName          interface{}   `json:"source-name"`
            SourceURL           interface{}   `json:"source-url"`
            TagNames            []interface{} `json:"tag-names"`
        } `json:"attributes"`
        Relationships struct {
            Organization struct {
                Data struct {
                    ID   string `json:"id"`
                    Type string `json:"type"`
                } `json:"data"`
            } `json:"organization"`
            CurrentRun struct {
                Data struct {
                    ID   string `json:"id"`
                    Type string `json:"type"`
                } `json:"data"`
                Links struct {
                    Related string `json:"related"`
                } `json:"links"`
            } `json:"current-run"`
            LatestRun struct {
                Data struct {
                    ID   string `json:"id"`
                    Type string `json:"type"`
                } `json:"data"`
                Links struct {
                    Related string `json:"related"`
                } `json:"links"`
            } `json:"latest-run"`
            Outputs struct {
                Data []interface{} `json:"data"`
            } `json:"outputs"`
            RemoteStateConsumers struct {
                Links struct {
                    Related string `json:"related"`
                } `json:"links"`
            } `json:"remote-state-consumers"`
            CurrentStateVersion struct {
                Data struct {
                    ID   string `json:"id"`
                    Type string `json:"type"`
                } `json:"data"`
                Links struct {
                    Related string `json:"related"`
                } `json:"links"`
            } `json:"current-state-version"`
            CurrentConfigurationVersion struct {
                Data struct {
                    ID   string `json:"id"`
                    Type string `json:"type"`
                } `json:"data"`
                Links struct {
                    Related string `json:"related"`
                } `json:"links"`
            } `json:"current-configuration-version"`
            AgentPool struct {
                Data interface{} `json:"data"`
            } `json:"agent-pool"`
            Readme struct {
                Data struct {
                    ID   string `json:"id"`
                    Type string `json:"type"`
                } `json:"data"`
            } `json:"readme"`
        } `json:"relationships"`
        Links struct {
            Self string `json:"self"`
        } `json:"links"`
    } `json:"data"`
    Links struct {
        Self  string      `json:"self"`
        First string      `json:"first"`
        Prev  interface{} `json:"prev"`
        Next  string      `json:"next"`
        Last  string      `json:"last"`
    } `json:"links"`
    Meta struct {
        StatusCounts struct {
            Pending            int `json:"pending"`
            PlanQueued         int `json:"plan-queued"`
            Planning           int `json:"planning"`
            Planned            int `json:"planned"`
            Confirmed          int `json:"confirmed"`
            ApplyQueued        int `json:"apply-queued"`
            Applying           int `json:"applying"`
            Applied            int `json:"applied"`
            Discarded          int `json:"discarded"`
            Errored            int `json:"errored"`
            Canceled           int `json:"canceled"`
            CostEstimating     int `json:"cost-estimating"`
            CostEstimated      int `json:"cost-estimated"`
            PolicyChecking     int `json:"policy-checking"`
            PolicyOverride     int `json:"policy-override"`
            PolicyChecked      int `json:"policy-checked"`
            PolicySoftFailed   int `json:"policy-soft-failed"`
            PlannedAndFinished int `json:"planned-and-finished"`
            PostPlanRunning    int `json:"post-plan-running"`
            PostPlanCompleted  int `json:"post-plan-completed"`
            PreApplyRunning    int `json:"pre-apply-running"`
            PreApplyCompleted  int `json:"pre-apply-completed"`
            Fetching           int `json:"fetching"`
            None               int `json:"none"`
            Total              int `json:"total"`
        } `json:"status-counts"`
        Pagination struct {
            CurrentPage int         `json:"current-page"`
            PageSize    int         `json:"page-size"`
            PrevPage    interface{} `json:"prev-page"`
            NextPage    int         `json:"next-page"`
            TotalPages  int         `json:"total-pages"`
            TotalCount  int         `json:"total-count"`
        } `json:"pagination"`
    } `json:"meta"`
}

我陷入了这两个相同错误的无限循环中,并试图创建一些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:

func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
// omitted API calls for brevity
// body holds the JSON response
body, err := ioutil.ReadAll(resp.Body)
// label my struct type as data
var data WorkspacesJSON
err = json.Unmarshal(body, data)
if err != nil {
panic(err)
}
var data2 []*WorkspacesJSON
for _, v := range data.Data {
if v.Relationships.CurrentConfigurationVersion.Data == " " {
data2 = append(data2, v)
}
}
}

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:

func (s *Server) getEmptyWorkSpaces(w http.ResponseWriter, r *http.Request) {
// omitted API calls for brevity
// body holds the JSON response
body, err := ioutil.ReadAll(resp.Body)
// label my struct type as data, this time attach []*
var data []*WorkspacesJSON
// added & in this new attempt
err = json.Unmarshal(body, &data)
if err != nil {
panic(err)
}
var data2 []*WorkspacesJSON
for _, v := range data.Data {
if v.Relationships.CurrentConfigurationVersion.Data == " " {
data2 = append(data2, v)
}
}
}

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

type WorkspacesJSON struct {
Data []struct {
ID         string `json:"id"`
Type       string `json:"type"`
Attributes struct {
AllowDestroyPlan           bool        `json:"allow-destroy-plan"`
AutoApply                  bool        `json:"auto-apply"`
AutoDestroyAt              interface{} `json:"auto-destroy-at"`
CreatedAt                  time.Time   `json:"created-at"`
Environment                string      `json:"environment"`
Locked                     bool        `json:"locked"`
Name                       string      `json:"name"`
QueueAllRuns               bool        `json:"queue-all-runs"`
SpeculativeEnabled         bool        `json:"speculative-enabled"`
StructuredRunOutputEnabled bool        `json:"structured-run-output-enabled"`
TerraformVersion           string      `json:"terraform-version"`
WorkingDirectory           string      `json:"working-directory"`
GlobalRemoteState          bool        `json:"global-remote-state"`
UpdatedAt                  time.Time   `json:"updated-at"`
ResourceCount              int         `json:"resource-count"`
ApplyDurationAverage       int         `json:"apply-duration-average"`
PlanDurationAverage        int         `json:"plan-duration-average"`
PolicyCheckFailures        int         `json:"policy-check-failures"`
RunFailures                int         `json:"run-failures"`
WorkspaceKpisRunsCount     int         `json:"workspace-kpis-runs-count"`
LatestChangeAt             time.Time   `json:"latest-change-at"`
Operations                 bool        `json:"operations"`
ExecutionMode              string      `json:"execution-mode"`
VcsRepo                    struct {
Branch            string `json:"branch"`
IngressSubmodules bool   `json:"ingress-submodules"`
Identifier        string `json:"identifier"`
DisplayIdentifier string `json:"display-identifier"`
OauthTokenID      string `json:"oauth-token-id"`
WebhookURL        string `json:"webhook-url"`
RepositoryHTTPURL string `json:"repository-http-url"`
ServiceProvider   string `json:"service-provider"`
} `json:"vcs-repo"`
VcsRepoIdentifier string `json:"vcs-repo-identifier"`
Permissions       struct {
CanUpdate              bool `json:"can-update"`
CanDestroy             bool `json:"can-destroy"`
CanQueueDestroy        bool `json:"can-queue-destroy"`
CanQueueRun            bool `json:"can-queue-run"`
CanQueueApply          bool `json:"can-queue-apply"`
CanReadStateVersions   bool `json:"can-read-state-versions"`
CanCreateStateVersions bool `json:"can-create-state-versions"`
CanReadVariable        bool `json:"can-read-variable"`
CanUpdateVariable      bool `json:"can-update-variable"`
CanLock                bool `json:"can-lock"`
CanUnlock              bool `json:"can-unlock"`
CanForceUnlock         bool `json:"can-force-unlock"`
CanReadSettings        bool `json:"can-read-settings"`
CanManageTags          bool `json:"can-manage-tags"`
} `json:"permissions"`
Actions struct {
IsDestroyable bool `json:"is-destroyable"`
} `json:"actions"`
Description         interface{}   `json:"description"`
FileTriggersEnabled bool          `json:"file-triggers-enabled"`
TriggerPrefixes     []interface{} `json:"trigger-prefixes"`
Source              string        `json:"source"`
SourceName          interface{}   `json:"source-name"`
SourceURL           interface{}   `json:"source-url"`
TagNames            []interface{} `json:"tag-names"`
} `json:"attributes"`
Relationships struct {
Organization struct {
Data struct {
ID   string `json:"id"`
Type string `json:"type"`
} `json:"data"`
} `json:"organization"`
CurrentRun struct {
Data struct {
ID   string `json:"id"`
Type string `json:"type"`
} `json:"data"`
Links struct {
Related string `json:"related"`
} `json:"links"`
} `json:"current-run"`
LatestRun struct {
Data struct {
ID   string `json:"id"`
Type string `json:"type"`
} `json:"data"`
Links struct {
Related string `json:"related"`
} `json:"links"`
} `json:"latest-run"`
Outputs struct {
Data []interface{} `json:"data"`
} `json:"outputs"`
RemoteStateConsumers struct {
Links struct {
Related string `json:"related"`
} `json:"links"`
} `json:"remote-state-consumers"`
CurrentStateVersion struct {
Data struct {
ID   string `json:"id"`
Type string `json:"type"`
} `json:"data"`
Links struct {
Related string `json:"related"`
} `json:"links"`
} `json:"current-state-version"`
CurrentConfigurationVersion struct {
Data struct {
ID   string `json:"id"`
Type string `json:"type"`
} `json:"data"`
Links struct {
Related string `json:"related"`
} `json:"links"`
} `json:"current-configuration-version"`
AgentPool struct {
Data interface{} `json:"data"`
} `json:"agent-pool"`
Readme struct {
Data struct {
ID   string `json:"id"`
Type string `json:"type"`
} `json:"data"`
} `json:"readme"`
} `json:"relationships"`
Links struct {
Self string `json:"self"`
} `json:"links"`
} `json:"data"`
Links struct {
Self  string      `json:"self"`
First string      `json:"first"`
Prev  interface{} `json:"prev"`
Next  string      `json:"next"`
Last  string      `json:"last"`
} `json:"links"`
Meta struct {
StatusCounts struct {
Pending            int `json:"pending"`
PlanQueued         int `json:"plan-queued"`
Planning           int `json:"planning"`
Planned            int `json:"planned"`
Confirmed          int `json:"confirmed"`
ApplyQueued        int `json:"apply-queued"`
Applying           int `json:"applying"`
Applied            int `json:"applied"`
Discarded          int `json:"discarded"`
Errored            int `json:"errored"`
Canceled           int `json:"canceled"`
CostEstimating     int `json:"cost-estimating"`
CostEstimated      int `json:"cost-estimated"`
PolicyChecking     int `json:"policy-checking"`
PolicyOverride     int `json:"policy-override"`
PolicyChecked      int `json:"policy-checked"`
PolicySoftFailed   int `json:"policy-soft-failed"`
PlannedAndFinished int `json:"planned-and-finished"`
PostPlanRunning    int `json:"post-plan-running"`
PostPlanCompleted  int `json:"post-plan-completed"`
PreApplyRunning    int `json:"pre-apply-running"`
PreApplyCompleted  int `json:"pre-apply-completed"`
Fetching           int `json:"fetching"`
None               int `json:"none"`
Total              int `json:"total"`
} `json:"status-counts"`
Pagination struct {
CurrentPage int         `json:"current-page"`
PageSize    int         `json:"page-size"`
PrevPage    interface{} `json:"prev-page"`
NextPage    int         `json:"next-page"`
TotalPages  int         `json:"total-pages"`
TotalCount  int         `json:"total-count"`
} `json:"pagination"`
} `json:"meta"`
}

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部分必须具有相同的类型,如下所示:

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

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:

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

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:

确定