Search code examples
reactjsarraystypescriptapiazure-devops-extensions

Trying to merge nested arrays within two separate arrays together and form one big array with nested arrays


I am using the azure-devops-exstension-api to create two arrays (each with several nested arrays), one is using the built-in GitRepository interface and the other is using the built-in GitCommitsRef interface. I am trying to use these arrays in a JSX.Element table and it works great when I use either of my arrays. But it does not look like I can have multiple itemProviders (one for each array) so at the moment I can only use one or the other.

I need to find a way to merge the nested arrays within each array together. here is the code I currently have to assemble both arrays:

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>
    );
}

I have tried concat, spread, and push in various ways and combinations but so far nothing has worked.

Currently, the two arrays are as follows (example):

repositories = [{name: name, size: size}, {name: name, size: size}]

lastCommmits = [{author: author, commitId: commitId}, {author: author, commitId: commitId}]

What I am hoping to accomplish is:

finalArray = [{name: name, size: size, author: author, commitId: commitId}, {name: name, size: size, author: author, commitId: commitId}]


Solution

  • As long as you can be confident that items at identical indices in each array should be related, and both arrays are the same length, then it's pretty straightforward:

    const finalArray = repositories.map((r, idx) => ({
      ...r,
      ...(lastCommits[idx] || {}),
    }));
    

    You could also implement this just with a for loop, it's just a bit less code to use map. for example:

    const finalArray = [];
    for (let i = 0; i < repositories.length; i++){
      finalArray.push({
       ...repositories[i],
       ...lastCommits[i],
      });
    }