'How do I compare 2 arrays in React render?

I am creating a dashboard in React, of which I am rendering data from JSON files to a table.

I want to compare the values from both JSON files and conditional render a className based on whether the values match or not.

The 2 JSON files are as follows:

test.json

{
    "applications": {
        "app1": {
            "version": "8.0.2"
        },
        "app2": {
            "version": "8.0.26"
        },
        "app3": {
            "version": "N/A"
        }
    }
}

goldenTest.json:

{
    "applications": {
        "app1": {
            "version": "10.0.0"
        },
        "app2": {
            "version": "8.0.26"
        },
        "app3": {
            "version": "N/A"
        }
    }
}

The goldenTemplate.json file contains the expected version of the applications. The test.json file contains the actual versions.

I want to check to see if the versions inside of test.json match goldenTemplate.json, if they do leave the table cell the same, but if they don't I want to render the table cell background red.

So far I have managed to render all data to the dashboard by adding the JSON contents to an array and using .map() to iterate over the files.

test.js:

import React, { Component } from "react";

import test from './test.json';
import golden from './goldenTest.json';

class Test extends Component {
    constructor(props) {
        super(props);

        this.state = {
            "test": test,
            "golden": golden
        }
    }

    render() {
        const { test, golden } = this.state;

        const goldenData = [golden];
        const testData = [test];

        const goldenSite = Object.keys(golden.applications);
        const testSite = Object.keys(test.applications);

        const allKeysArray = [...new Set([...goldenSite, ...testSite])];
        const allKeysSorted = allKeysArray.sort();

        return (
            <div className="container-fluid">
                <div className="row justify-content-center">
                    <div className="col-12">
                        <p className="display-4 text-center mb-3">Test Data</p>
                        <table className="table table-hover table-responsive" id="all-data-table">
                            <thead className="sticky-top bg-white">
                                <tr>
                                    <th scope="col">Application Name</th>
                                    <th scope="col">Golden Version</th>
                                    <th scope="col">Test Version</th>
                                </tr>
                            </thead>
                            <tbody>
                                {allKeysSorted.map((k) => (
                                    <tr>
                                        <td>{k}</td>
                                        {goldenData.map((g) => (
                                            <td>{g.applications[k] && g.applications[k]["version"] ? g.applications[k]["version"] : "Not Present"}</td>
                                        ))}
                                        {testData.map((t) => (
                                            <td>{t.applications[k] && t.applications[k]["version"] ? t.applications[k]["version"] : "NULL"}</td>
                                        ))}
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        )
    }
}


export default Test;

I know I need to add something like className={t.applications["version"] !== g.applications["version"] ? "text-danger" : ""} but I can't figure out how to .map() 2 arrays at the same time.

Any help would be appreciative.



Solution 1:[1]

i have just quickly came up with this portion of code... of course you would need to adjust output to your needs.

  const colorBackgroundInRed = (test, expected) => {
    if (typeof test === 'object') {
      for (const key of Object.keys(test)) {
        const exist = expected[key];
        if (!exist) {
          return { colorBg: true, diff: `${key} does not exist in expected json` };
        }
        console.log( test[key], exist);
        const res = colorBackgroundInRed(test[key], exist);
        if (res.colorBg) {
          return res;
        }
      }
    }
    if (typeof test === 'string') {
      if (test !== expected) {
        return {
          colorBg: true,
          diff: `value of test json ${test} does not match with expected: ${expected}`,
        };
      }
    }
    return {
      colorBg: false,
      diff: `none`,
    };
  };

const test = {
    applications: {
      app1: {
        version: '8.0.2',
      },
      app2: {
        version: '8.0.26',
      },
      app3: {
        version: 'N/A',
      },
    },
  };
  const expected = {
    applications: {
      app1: {
        version: '10.0.0',
      },
      app2: {
        version: '8.0.26',
      },
      app3: {
        version: 'N/A',
      },
    },
  };

const colorBackgroundInRed = (test, expected) => {
    if (typeof test === 'object') {
      for (const key of Object.keys(test)) {
        const exist = expected[key];
        if (!exist) {
          return { colorBg: true, diff: `${key} does not exist in expected json` };
        }
        console.log(test[key], exist);
        const res = colorBackgroundInRed(test[key], exist);
        if (res.colorBg) {
          return res;
        }
      }
    }
    if (typeof test === 'string') {
      if (test !== expected) {
        return {
          colorBg: true,
          diff: `value of test json ${test} does not match with expected: ${expected}`,
        };
      }
    }
    return {
      colorBg: false,
      diff: `none`,
    };
  };
const result = colorBackgroundInRed(test, expected);
  console.log('color me ', result.colorBg, ' because of - ', result.diff);

Solution 2:[2]

I figured it out.

I was able to .map() inside of the className property and it gave me the expected output.

<td className={goldenSites.map((gs) => (s.applications[k] && s.applications[k]["version"] && gs.applications[k] && gs.applications[k]["version"] && gs.applications[k]["version"] !== "N/A" && s.applications[k]["version"] === gs.applications[k]["version"] ? "" : "bg-danger"))}>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stefan Zivkovic
Solution 2 ATN