2

I have a function within NodeJS which is returning Json Javascript object.

let rows = function1();

Here rows look like:

"rows": [
    {
    "Hostname": "abc123",
    "name": "name1",
    "Status": "PASS",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc123",
    "name": "name2",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name1",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name2",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    }
]

Here, rows can have any number of Json objects for the same Hostname key:

"rows": [
    {
    "Hostname": "abc123",
    "name": "name1",
    "Status": "PASS",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc123",
    "name": "name2",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc123",
    "name": "name3",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
 ...
    {
    "Hostname": "abc235",
    "name": "name1",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name2",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name3",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    }
...
]

I want to modify the rows array such that all Javascript objects belonging to one Hostname are converted into a single Json object:

"rows": [
    {
    "Hostname": "abc123",
    "name1Status": "PASS",
    "name1Heading": "Not Applicable"
    "name2Status": "FAIL",
    "name2Heading": "Not Applicable"
    "name3Status": "FAIL",
    "name3Heading": "Not Applicable"
    ...
    },
    {
    "Hostname": "abc235",
    "name1Status": "FAIL",
    "name1Heading": "Not Applicable"
    "name2Status": "FAIL",
    "name2Heading": "Not Applicable"
    "name3Status": "FAIL",
    "name3Heading": "Not Applicable"
    ...
    }
]

I have written the following code but it overwrites all key value pairs and shows Json objects related to the last Hostname only

const res = rows.reduce((acc, rec) => {
    let result = { ...acc, [`Hostname`]: rec.Hostname,  [`${rec.name}Status`]: rec.Status, [`${rec.name}Heading`]: rec.Heading  }
    return result
}, [])

{
    "Hostname": "abc235",
    "name1Status": "FAIL",
    "name1Heading": "Not Applicable"
    "name2Status": "FAIL",
    "name2Heading": "Not Applicable"
    "name3Status": "FAIL",
    "name3Heading": "Not Applicable"
}

There could be some form of for loop outside of res so that it takes into account all distinct Hostname keys

3
  • Your desired output is not very well normalized (naming things like nameNUMBERStatus). Is there a specific reason it has to look like that, or is that something you came up with? Something like { "Hostname": "abc235", "rows": [...] }, { "Hostname", "def234", "rows": [...] } would be much cleaner. Commented Apr 27, 2020 at 6:31
  • 1
    Using numbered properties like name1Status and name2Status and name3Status are hard for the consumer of this object to use. they would literally have to manufacture property names and see if they exist. Much better to offer an array of result objects that can be handled like any array of results. Commented Apr 27, 2020 at 6:37
  • Also, please use the proper terminology. JSON is a text format. These are Javascript objects. Commented Apr 27, 2020 at 6:38

2 Answers 2

1

You could take an object for grouping and return the grouped values.

var data = [{ Hostname: "abc123", name: "name1", Status: "PASS", Heading: "Not Applicable" }, { Hostname: "abc123", name: "name2", Status: "FAIL", Heading: "Not Applicable" }, { Hostname: "abc235", name: "name1", Status: "FAIL", Heading: "Not Applicable" }, { Hostname: "abc235", name: "name2", Status: "FAIL", Heading: "Not Applicable" }],
    keys = ["Status", "Heading"],
    result = Object.values(data.reduce((r, { Hostname, name, ...o }) => {
        r[Hostname] = r[Hostname] || { Hostname };
        keys.forEach(k => r[Hostname][name + k] = o[k]);
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

1

JSON elements?

Anyway: this reducer should do it (using a helper method).

const createEntry = (obj, value) => 
  ({...obj, [`${value.name}Status`]: value.Status, [`${value.name}Heading`]: value.Heading});

console.log(getRows()
  .reduce( (acc, value) => (
      {...acc, [value.Hostname]: createEntry(acc[value.Hostname], value)} )
   , {})
);

function getRows() {
  return [
    {
    "Hostname": "abc123",
    "name": "name1",
    "Status": "PASS",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc123",
    "name": "name2",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc123",
    "name": "name3",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name1",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name2",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    },
    {
    "Hostname": "abc235",
    "name": "name3",
    "Status": "FAIL",
    "Heading": "Not Applicable"
    }
  ];
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

2 Comments

Actually as per the requirement, my output should same as given in the question. { "Hostname": "abc123", "name1Status": "PASS", "name1Heading": "Not Applicable" "name2Status": "FAIL", "name2Heading": "Not Applicable" "name3Status": "FAIL", "name3Heading": "Not Applicable" ... }, { "Hostname": "abc235", "name1Status": "FAIL", "name1Heading": "Not Applicable" "name2Status": "FAIL", "name2Heading": "Not Applicable" "name3Status": "FAIL", "name3Heading": "Not Applicable" ... }
@meallhour Modified

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.