0
\$\begingroup\$

Looking a way to reduce the below code to get comma separated values from the list of arrays By using ECMA or plain old vanilla JS. How should we achieve this?

Actual Array Data:

[{
    ansBook: "046H",
    ansPersonId: "2044000102",
    bookNbr: "046H",
    dns: "0",
    examCode: "20717010",
    examShortTitle: "QA-ATAG-Director of Applications",
    nar: "0",
    personId: "2044000102",
    pull: "0",
    wn: "0",
    corrCd: 1
  },
  {
    ansBook: "046I",
    ansPersonId: "2044000102",
    bookNbr: "046I",
    dns: "0",
    examCode: "20721010",
    examShortTitle: "QA-ATAG-Plans Examinier",
    nar: "0",
    personId: "2044000102",
    pull: "0",
    wn: "0",
    corrCd: 1
  }
];

Expected Result:

{
  "PersonIds": "2044000102, 2044000102",
  "BookLetCodes": "046H, 046I",
  "ExamNumbers": "20717010, 20721010",
  "ExamTitles": "QA-ATAG-Director of Applications, QA-ATAG-Plans Examinier"
}

As I am getting the expected result. But I need to reduce and improvise the performance performed on it..

let seriesDataSet = [{
    ansBook: "046H",
    ansPersonId: "2044000102",
    bookNbr: "046H",
    dns: "0",
    examCode: "20717010",
    examShortTitle: "QA-ATAG-Director of Applications",
    nar: "0",
    personId: "2044000102",
    pull: "0",
    wn: "0",
    corrCd: 1
  },
  {
    ansBook: "046I",
    ansPersonId: "2044000102",
    bookNbr: "046I",
    dns: "0",
    examCode: "20721010",
    examShortTitle: "QA-ATAG-Plans Examinier",
    nar: "0",
    personId: "2044000102",
    pull: "0",
    wn: "0",
    corrCd: 1
  }
];

let auditingInfo = {};
auditingInfo = (seriesDataSet).filter(w => (w.dns == '0' && w.pull == '0') && w.corrCd == 1)
  .map(e => ({
    PersonIds: e.personId,
    BookLetCodes: e.ansBook,
    ExamNumbers: e.examCode,
    ExamTitles: e.examShortTitle
  }))
console.log(auditingInfo)

let auditingDetails = {
  PersonIds: auditingInfo.map(x => x.PersonIds).join(', '),
  BookLetCodes: auditingInfo.map(x => x.BookLetCodes).join(', '),
  ExamNumbers: auditingInfo.map(x => x.ExamNumbers).join(', '),
  ExamTitles: auditingInfo.map(x => x.ExamTitles).join(', ')
}
console.log('______________________________________________')
console.log('Expected Result:')
console.log(auditingDetails)
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

OR

let ScoringApprove: Array<number> = [];
ScoringApprove = new List<SeriesReportsDataset>(this.tempSeriesDataSet)
                .Where(w => (w.dns == '0' && w.pull == '0') && w.corrCd == 1)
                .Select(s => s.scannedResponseID).ToArray();
\$\endgroup\$
2
  • \$\begingroup\$ Consider one single reduce instead of the 5 map calls. \$\endgroup\$
    – sschmeck
    Commented May 31, 2021 at 6:45
  • \$\begingroup\$ @Blindman67, Anything you could add apart from these answers. I saw your post went deleted, before I could read... I am supporting larger audience bringing up their own approaches whether it's right or wrong \$\endgroup\$ Commented May 31, 2021 at 13:56

2 Answers 2

1
\$\begingroup\$

Honestly, structure-wise, your code seems pretty good. I've just got a handful of minor code-cleanup suggestions:

  • Use === instead of ==, == does some magical type coercion, and can create unexpected results.
  • You've got some unenesary parentheses here: auditingInfo = (seriesDataSet).filter(w => (w.dns === '0' && w.pull === '0') && w.corrCd === 1) - you can take out the parentheses around (seriesDataSet) and (w.dns === '0' && w.pull === '0')
  • What's the reason for initializing auditingInfo to {}, then immediately setting it to a different value? Just do it in one go. For example:
// instead of
let auditingInfo = {};
auditingInfo = ...
// just do
let auditingInfo = ...;

You're using a .map() to extract and rename values from your data set, then the next thing you do is some .map()s again to extract out specific values. Why not take out the first .map() entirely?

After applying these suggestions, you'll be left with this:

let auditingInfo = seriesDataSet.filter(w => w.dns === "0" && w.pull === "0" && w.corrCd === 1);

let auditingDetails = {
  PersonIds: auditingInfo.map(x => x.personId).join(", "),
  BookLetCodes: auditingInfo.map(x => x.ansBook).join(", "),
  ExamNumbers: auditingInfo.map(x => x.examCode).join(", "),
  ExamTitles: auditingInfo.map(x => x.examShortTitle).join(", ")
};

Finally, you had also asked about improving performance. You're not doing anything slow algorithm-wise, so there's not a whole lot of performance gains you can squeeze out of this. I wouldn't bother unless you really need it, in which case, you can try out different micro-optimizations and run performance tests on your target platforms to see which optimizations help the most. (some optimizations could speed things up on one platform and slow them down on another). Any of these types of optimizations will reduce the readability of your code, so only apply them if they make a significant enough impact.

A couple of optimization ideas you can try out that may help out, or may make things worse:

  • Use a single for loop instead of using .filter() and multiple .map() calls.
  • Instead of array.join(), gradually build the string.
  • If you have a large dataset, see if you can gradually consume a stream of data, instead of loading the whole thing into memory, all at once.
\$\endgroup\$
1
\$\begingroup\$

To reduce the array loops you could use one single reduce function instead of several map calls. The example below uses Object destructuring within the reduce callback, addition assignments and the ternary condition operator.

const auditingDetails2 = seriesDataSet
  .filter(w => w.dns === '0' && w.pull === '0' && w.corrCd === 1)
  .reduce((acc, {personId, ansBook, examCode, examShortTitle}) => {
      acc.PersonIds +=  acc.PersonIds ? `, ${personId}` : personId
      acc.BookLetCodes += acc.BookLetCodes ? `, ${ansBook}` : ansBook
      acc.ExamNumbers += acc.ExamNumbers ? `, ${examCode}` : examCode
      acc.ExamTitles += acc.ExamTitles ? `, ${examShortTitle}` : examShortTitle 
      return acc;
  }, {PersonIds: '', BookLetCodes: '', ExamNumbers: '', ExamTitles: ''} )

Since the callback contains some redundancy, we can introduce a helper function, appendValue.

function appendValue(obj: Record<string, string>, property: string, value: string) {
  obj[property] += obj[property] ? `, ${value}` : value
}

const auditingDetails3 = seriesDataSet
  .filter(w => w.dns === '0' && w.pull === '0' && w.corrCd === 1)
  .reduce((acc, { personId, ansBook, examCode, examShortTitle }) => {
    appendValue(acc, 'PersonIds', personId)
    appendValue(acc, 'BookLetCodes', ansBook)
    appendValue(acc, 'ExamNumbers', examCode)
    appendValue(acc, 'ExamTitles', examShortTitle)
    return acc;
  }, { PersonIds: '', BookLetCodes: '', ExamNumbers: '', ExamTitles: '' })
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.