You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并GitRepository与GitCommitRef数组用于Azure DevOps扩展表格

问题

我正在用azure-devops-exstension-api创建两个数组(各自包含若干对象),一个基于内置的GitRepository接口,另一个基于内置的GitCommitRef接口。我想把这些数据放到JSX.Element表格里,单独用任意一个数组都能正常显示,但表格只能配置一个itemProvider,现在只能二选一。

我需要把两个数组的对应对象合并,以下是当前的代码:

private async initializeComponent() {
    const projects = await getClient(CoreRestClient).getProjects();
    var repositories = [] as GitRepository[];
    var lastCommits = [] as GitCommitRef [];
    console.log("Before Get repos")
    for (let i = 0; i < projects.length; i++) {
        const repos: GitRepository[] = await getClient(GitRestClient).getRepositories(projects[i].name);
        console.log(repos);
        repositories = repositories.concat(repos);
        console.log(repositories);
    }
    //Sort the list in alphabetical on repository name
    repositories = repositories.sort((a, b) => {
        return a.name.localeCompare(b.name)
    });
    console.log("Retrieving commit Date");
    //Retrieve last commit for each repo
    for (let i = 0; i < repositories.length; i++){
        const repoName: string = repositories[i].name;
        const projName: string = repositories[i].project.name;
        console.log("Repository: " + repoName);
        const filter: GitQueryCommitsCriteria = { $top: 1 }
        console.log("Project: " + projName);
        console.log("Filter: " + filter);
        const commit: GitCommitRef[] = await getClient(GitRestClient).getCommits(repoName, filter, projName);
        console.log(commit);
        lastCommits = lastCommits.concat(commit);
        console.log(lastCommits);
    }
    //var fullArray = lastCommits.concat(repositories); -attempt at concat
    //repositories = [...lastCommits, ...repositories]; -attempt at Spread
    this.setState({
        projects: new ArrayItemProvider(projects),
        gitRepos: new ArrayItemProvider(repositories),
        gitCommits: new ArrayItemProvider(lastCommits),
        nbrRepos: repositories.length
    });
}

public render(): JSX.Element {
    return (
        <Page className="page-pivot flex-grow">

            <Header title={"Their repositories (" + this.state.nbrRepos + ")"}
                titleSize={TitleSize.Medium} />

            <div className="git-list-pivot">
                {
                    !this.state.gitRepos &&
                    !this.state.gitCommits &&
                    <p>Loading...</p>
                }
                {
                    this.state.gitRepos &&
                    this.state.gitCommits &&
                    <Table
                        columns={this.state.columns}
                        itemProvider={this.state.gitCommits}
                    />
                }
            </div>

        </Page>
    );
}

我试过concat、spread、push等方法都没成功。当前两个数组的结构示例:

repositories = [{name: "repo1", size: 123}, {name: "repo2", size: 456}]
lastCommits = [{author: "user1", commitId: "abc123"}, {author: "user2", commitId: "def456"}]

我想要的合并结果:

finalArray = [{name: "repo1", size: 123, author: "user1", commitId: "abc123"}, {name: "repo2", size: 456, author: "user2", commitId: "def456"}]
解决方案

核心思路是按索引将两个数组的对应对象合并,因为repositories和lastCommits是一一对应的(每个仓库对应它的最新提交),所以可以用map遍历仓库数组,同时取出对应索引的提交对象,将两者的属性合并。

修改步骤

  1. 在获取完所有提交后,创建合并后的数组:
// 合并两个数组的对应对象,处理可能的空提交情况
const finalArray = repositories.map((repo, index) => {
    const commit = lastCommits[index] || {}; // 防止某个仓库无提交导致报错
    return { ...repo, ...commit };
});
  1. 更新setState,新增合并后的ArrayItemProvider:
this.setState({
    projects: new ArrayItemProvider(projects),
    gitRepos: new ArrayItemProvider(repositories),
    gitCommits: new ArrayItemProvider(lastCommits),
    mergedRepoData: new ArrayItemProvider(finalArray), // 合并后的数据源
    nbrRepos: repositories.length
});
  1. 在render中使用合并后的数据源:
{
    this.state.mergedRepoData &&
    <Table
        columns={this.state.columns}
        itemProvider={this.state.mergedRepoData}
    />
}

完整修改后的initializeComponent方法

private async initializeComponent() {
    const projects = await getClient(CoreRestClient).getProjects();
    var repositories = [] as GitRepository[];
    var lastCommits = [] as GitCommitRef [];

    // 获取所有项目下的仓库
    for (let i = 0; i < projects.length; i++) {
        const repos: GitRepository[] = await getClient(GitRestClient).getRepositories(projects[i].name);
        repositories = repositories.concat(repos);
    }
    // 按仓库名称排序
    repositories = repositories.sort((a, b) => a.name.localeCompare(b.name));
    
    // 获取每个仓库的最新提交
    for (let i = 0; i < repositories.length; i++){
        const repoName = repositories[i].name;
        const projName = repositories[i].project.name;
        const filter: GitQueryCommitsCriteria = { $top: 1 };
        const commit = await getClient(GitRestClient).getCommits(repoName, filter, projName);
        lastCommits = lastCommits.concat(commit);
    }

    // 合并仓库与提交数据
    const finalArray = repositories.map((repo, index) => {
        const commit = lastCommits[index] || {};
        return { ...repo, ...commit };
    });

    this.setState({
        projects: new ArrayItemProvider(projects),
        gitRepos: new ArrayItemProvider(repositories),
        gitCommits: new ArrayItemProvider(lastCommits),
        mergedRepoData: new ArrayItemProvider(finalArray),
        nbrRepos: repositories.length
    });
}

说明

  • 用map遍历仓库数组时,通过index关联lastCommits中的对应提交,保证数据一一匹配。
  • 添加|| {}处理无提交的仓库,避免合并时出现undefined导致的异常。
  • 合并后的对象同时包含GitRepository和GitCommitRef的所有属性,可直接在表格列配置中使用这些属性。

内容的提问来源于stack exchange,提问作者Keebler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:10:21