Group and sort array - javascript

I have data that is coming from the server like this
let value = [
{
'commongId': 1,
'principal': true,
'creationDate': '2019-11-03:40:00'
},
{
'commongId': 2,
'principal': false,
'creationDate': '2017-10-25T01:35:00'
},
{
'commongId': 2,
'principal': true,
'creationDate': '2019-05-25T08:00:00'
},
{
'commongId': 1,
'principal': false,
'creationDate': '2018-11-25T09:40:00'
},
{
'commongId': 1,
'principal': false,
'creationDate': '2017-11-25T09:40:00'
},
{
'commongId': 2,
'principal': false,
'creationDate': '2018-05-25T08:00:00'
},
]
I want to transform it in a way that the courses are grouped by commonId, and that the principal course of each 'id' should appear first, and the rest of the courses belonging to the same commonId come after that principal course sorted by the creation date (asc).
So basically the output should be
let value = [
{
commongId: 1,
principal: true,
creationDate: '2019-11-03:40:00'
},
{
commongId: 1,
principal: false,
creationDate: '2017-11-25T09:40:00'
},
{
commongId: 1,
principal: false,
creationDate: '2018-11-25T09:40:00'
},
{
commongId: 2,
principal: true,
creationDate: '2019-05-25T08:00:00'
},
{
commongId: 2,
principal: false,
creationDate: '2017-10-25T01:35:00'
},
{
commongId: 2,
principal: false,
creationDate: '2018-05-25T08:00:00'
}
];
I have a working solution, which in my opinion looks horrible and too complicated.
// function to group the the courses by commonId
const groupBy = (data, keyFn) =>
data.reduce((agg, item) => {
const group = keyFn(item);
agg[group] = [...(agg[group] || []), item];
return agg;
}, {});
let transformedValue = groupBy(courses, item => item.commonId);
//removing the keys from the array of objects
transformedValue = Object.keys(transformedValue).map(k => transformedValue[k]);
// sorting each inner array by creationDate
transformedValue = transformedValue.map(el => {
let modified = el.sort((a, b) =>
moment(a.creationDate).diff(moment(b.creationDate))
);
// pushing the principal object of each array to the top
const foundIndex = modified.findIndex(element => element.principal);
if (foundIndex > -1) {
const foundElement = modified.find(element => element.principal);
modified.splice(foundIndex, 1);
modified.unshift(foundElement);
}
return modified;
});
// flattening the array to one level
transformedValue = transformedValue.flat();
// using the transformed value in the subscription
of(transformedValue).subscribe(p => {
this.dataToShow = p;
});

You could use sort like this.
const value=[{commongId:1,principal:true,creationDate:"2019-11-03:40:00"},{commongId:2,principal:false,creationDate:"2017-10-25T01:35:00"},{commongId:2,principal:true,creationDate:"2019-05-25T08:00:00"},{commongId:1,principal:false,creationDate:"2018-11-25T09:40:00"},{commongId:1,principal:false,creationDate:"2017-11-25T09:40:00"},{commongId:2,principal:false,creationDate:"2018-05-25T08:00:00"},];
value.sort((a, b) => a.commongId - b.commongId
|| b.principal - a.principal
|| a.creationDate.localeCompare(b.creationDate)
)
console.log(value)
The array will first be sorted based on commongId. If both have the same commongId, the subtraction will return 0. So, || will check the next expression because 0 is falsy value.
Then, it will be sorted based on principal. You can subtract 2 boolean values because it returns 1, -1 or 0 based on the value.
true - false === 1
false - true === -1
true - true === 0
If they still have the same value for commongId and principal, the array will be sorted based on the creationDate. Since the dates are in the ISO format, you can do a string comparison using localeCompare. If the date is in some other format, you could do
new Date(a.creationDate) - new Date(b.creationDate)

Use rxjs map and lodash groupBy.
of(response).pipe(
map(response => _groupBy(moveToFirst(response, item => item.principal === true)), 'commonId')
);
Where moveToFirst is a custom method to move the required item to Index 0.

Related

How to expose objects to a given pattern?

I automatically generate an array of objects in a random order. This means that the initial order of objects can be different.
var a = [{account: true},{name: true},{amount: true},{address: true}];
or
var a = [{name: true},{account: true},{amount: true},{address: true}];
How to expose objects to a given pattern?
var a = [{amount: true},{address: true},{account: true},{name: true}];
How can I arrange the automatically generated elements in a different order each time in a special order? I need the items to be in order - amount, address, account, name.
AND I have the solution!
var order = [{account: true},{name: true},{amount: true},{address: true}];
var pattern = [{amount: true},{address: true},{account: true},{name: true}];
var sort = pattern.map(pattern => order.find(order => order[0] === pattern[0]));
console.log(sort); //[{amount: true},{address: true},{account: true},{name: true}]
I'm not able to get a correct sort using your code. It seems to return an array with all the same elements of whatever is the first element of the order array.
[{ account: true },{ account: true },{ account: true },{ account: true }]
const order = [
{ account: true },
{ name: true },
{ amount: true },
{ address: true }
];
const pattern = [
{ amount: true },
{ address: true },
{ account: true },
{ name: true }
];
var sort = pattern.map((pattern) =>
order.find((order) => order[0] === pattern[0])
);
console.log("unsorted: ", JSON.stringify(order));
console.log("sorted: ", JSON.stringify(sort));
Here's a sort that does appear to sort your array element objects.
const sortedData = data.sort(
(a, b) =>
!!b.amount - !!a.amount ||
!!b.address - !!a.address ||
!!b.account - !!a.account ||
!!b.name - !!a.name
);
This works by coercing the undefined values to a boolean (i.e. undefined -> false) and then uses numerical comparison by again coercing the boolean values to type number (true -> 1, false -> 0), which results in sort comparator result values of [-1, 0, 1].
const data = [
{ account: true },
{ name: true },
{ amount: true },
{ address: true }
];
console.log("unsorted: ", JSON.stringify(data));
const sortedData = data.sort(
(a, b) =>
!!b.amount - !!a.amount ||
!!b.address - !!a.address ||
!!b.account - !!a.account ||
!!b.name - !!a.name
);
console.log("sorted: ", JSON.stringify(sortedData));

Use sort to sort by preference?

I have an array of objects that returns 3 possible sensitivity values: "LOW", "MEDIUM", "HIGH". However with the code below it is sorting in "HIGH - MEDIUM and LOW" respectively in ascending order and I wish it to return "HIGH - MEDIUM and LOW". What can I fix in this code?
In this function I compare the sensitivities received in the array
orderItemsByOrderOption = (items) => {
switch (this.state.selectedOrderOption.column) {
case "sensitivity":
return items.sort((a, b) => {
if (a.sensitivity > b.sensitivity) {
return 1;
}
if (a.sensitivity < b.sensitivity) {
return -1;
}
// a must be equal to b
return 0;
});
You could create an array with desired order and use the index of your array elements' sensitivity in this array for sorting.
Example
const arr = [
{ sensitivity: "MEDIUM" },
{ sensitivity: "LOW" },
{ sensitivity: "HIGH" }
];
const order = ["HIGH", "MEDIUM", "LOW"];
arr.sort((a, b) => order.indexOf(a.sensitivity) - order.indexOf(b.sensitivity));
console.log(arr);
There is a way is to convert rank into numeric value and compare that value
const data = [
{ id: 1, sensitivity: "LOW" },
{ id: 2, sensitivity: "HIGH" },
{ id: 3, sensitivity: "LOW" },
{ id: 4, sensitivity: "MEDIUM" },
{ id: 5, sensitivity: "HIGH" },
{ id: 6, sensitivity: "MEDIUM" },
];
const getRankInNum = (el) =>
({
HIGH: 2,
MEDIUM: 1,
LOW: 0,
}[el.sensitivity] || -1);
const res = data.sort((a, b) => getRankInNum(b) - getRankInNum(a));
console.log(res);
You could create a sort order lookup that maps HIGH, MEDIUM, and LOW to numeric values since sorting them alphabetically doesn't make sense.
const sensitivitySortOrder = {
HIGH: 0,
MEDIUM: 1,
LOW: 2
};
orderItemsByOrderOption = (items) => {
switch (this.state.selectedOrderOption.column) {
case "sensitivity":
return items.sort((a, b) => {
const aRank = sensitivitySortOrder[a.sensitivity];
const bRank = sensitivitySortOrder[b.sensitivity];
if (aRank > bRank) {
return 1;
}
if (aRank < bRank) {
return -1;
}
// a must be equal to b
return 0;
});

Need help by mapping a array

I have this Array with 6 different dates from db:
[{"_id":{"source":"2019-04-06","status":false},"count":1},
{"_id":{"source":"2019-04-06","status":true},"count":1},
{"_id":{"source":"2019-03-24","status":false},"count":2},
{"_id":{"source":"2019-03-24","status":true},"count":1},
{"_id":{"source":"2019-03-23","status":false},"count":3},
{"_id":{"source":"2019-03-08","status":false},"count":1},
{"_id":{"source":"2019-02-02","status":true},"count":1},
{"_id":{"source":"2019-02-02","status":false},"count":2},
{"_id":{"source":"2019-01-29","status":false},"count":1}]
What i need are 2 Arrays with the length of 6 items and the value of "count"
If only status "true" exists for a date, then i need to push a count: "0" to the false-array.
And if only status "false" exists for a date, then i need to push a count: "0" to the true-array.
It should look like this:
Arrayforstatusfalse = [1,2,3,1,2,1]
Arrayforstatustrue = [1,1,0,0,1,0]
But what i get is this:
Arrayforstatusfalse = [1,2,3,1,2,1]
Arrayforstatustrue = [1,1,1]
Update:
Sorry for this ugly code. i will be more precise. And thanks for your help.
this.responsedata = input
this.line1 = output for all the "false"
this.line2 = output for all the "true"
I loop over input data with condition and push it into the new arrays:
for (var i=0; i<this.responsedata.length;i++) {
if (this.responsedata[i]._id.status === true ) {
console.log('true exits for date: ' + JSON.stringify(this.responsedata[i]._id.source) + JSON.stringify(this.responsedata[i].count) )
this.line2.push(this.responsedata[i])
}
if (this.responsedata[i]._id.status === false ) {
console.log('false exits for date: ' + JSON.stringify(this.responsedata[i]._id.source) + JSON.stringify(this.responsedata[i].count) )
this.line1.push(this.responsedata[i])
}
}
Console :
[Log] false exits for date: "2019-04-06"1
[Log] true exits for date: "2019-04-06"1
[Log] false exits for date: "2019-03-24"2
[Log] true exits for date: "2019-03-24"1
[Log] false exits for date: "2019-03-23"3
[Log] false exits for date: "2019-03-08"1
[Log] true exits for date: "2019-02-02"1
[Log] false exits for date: "2019-02-02"2
[Log] false exits for date: "2019-01-29"1
[Log] line1[1,2,3,1,2,1]
[Log] line2[1,1,1]
And here i need line2 = [1,1,0,0,1,0]
because i need a 0 "if not exits on this date"..
You could take a Map for keeping the same index in insertation order of the given data.
var array = [{ _id: { source: "2019-04-06", status: false }, count: 1 }, { _id: { source: "2019-04-06", status: true }, count: 1 }, { _id: { source: "2019-03-24", status: false }, count: 2 }, { _id: { source: "2019-03-24", status: true }, count: 1 }, { _id: { source: "2019-03-23", status: false }, count: 3 }, { _id: { source: "2019-03-08", status: false }, count: 1 }, { _id: { source: "2019-02-02", status: true }, count: 1 }, { _id: { source: "2019-02-02", status: false }, count: 2 }, { _id: { source: "2019-01-29", status: false }, count: 1 }],
result = array.reduce((m => (r, { _id: { source, status }, count }) => {
var index = m.get(source);
if (index === undefined) {
m.set(source, index = m.size);
r.true[index] = 0;
r.false[index] = 0;
}
r[status][index] = count;
return r;
})(new Map), { true: [], false: [] }),
{ true: trues, false: falses } = result;
console.log(...trues);
console.log(...falses);
You can use reduce() to summarize the array into an object using the source as key. Convert the object into array using Object.entries and reduce it again to convert the inner child object into an array.
Use destructuring assignment syntax to assign into variables.
let array = [{"_id":{"source":"2019-04-06","status":false},"count":1},{"_id":{"source":"2019-04-06","status":true},"count":1},{"_id":{"source":"2019-03-24","status":false},"count":2},{"_id":{"source":"2019-03-24","status":true},"count":1},{"_id":{"source":"2019-03-23","status":false},"count":3},{"_id":{"source":"2019-03-08","status":false},"count":1},{"_id":{"source":"2019-02-02","status":true},"count":1},{"_id":{"source":"2019-02-02","status":false},"count":2},{"_id":{"source":"2019-01-29","status":false},"count":1}];
let {Arrayforstatusfalse,Arrayforstatustrue} = Object.entries(array.reduce((c, v) => {
c.Arrayforstatustrue[v._id.source] = c.Arrayforstatustrue[v._id.source] || 0;
c.Arrayforstatusfalse[v._id.source] = c.Arrayforstatusfalse[v._id.source] || 0;
if (v._id.status) c.Arrayforstatustrue[v._id.source] += v.count;
else c.Arrayforstatusfalse[v._id.source] += v.count;
return c;
}, {Arrayforstatusfalse: {},Arrayforstatustrue: {}}))
.reduce((c, [k, o]) => Object.assign(c, {[k]: Object.values(o)}), {});
console.log(Arrayforstatusfalse);
console.log(Arrayforstatustrue);
This?
const data = [
{"_id":{"source":"2019-04-06","status":false},"count":1},
{"_id":{"source":"2019-04-06","status":true},"count":1},
{"_id":{"source":"2019-03-24","status":false},"count":2},
{"_id":{"source":"2019-03-24","status":true},"count":1},
{"_id":{"source":"2019-03-23","status":false},"count":3},
{"_id":{"source":"2019-03-08","status":false},"count":1},
{"_id":{"source":"2019-02-02","status":true},"count":1},
{"_id":{"source":"2019-02-02","status":false},"count":2},
{"_id":{"source":"2019-01-29","status":false},"count":1},
];
const byDate = {};
data.forEach((f, ndx) => {
byDate[f._id.source] = byDate[f._id.source] || [];
byDate[f._id.source].push(f);
});
function mapCounts(byDate, status) {
return Object.values(byDate).map(d => {
const ndx = d.findIndex(e => e._id.status === status);
return ndx >= 0 ? d[ndx].count : 0;
});
}
const falseForDate = mapCounts(byDate, false);
const trueForDate = mapCounts(byDate, true);
console.log(falseForDate.join(','));
console.log(trueForDate.join(','));
note I'm curious what this is acutally for. The code above will not handle things if there are 3 of the same date because then there are would either be 2 counts for true or 2 for false. Which count to use. Similarly the same sitatuion arrises if their are 2 trues or 2 falses for the same date (same issue really). Maybe you want to sum the counts for true or false by date?
In that case
const data = [
{"_id":{"source":"2019-04-06","status":false},"count":1},
{"_id":{"source":"2019-04-06","status":true},"count":1},
{"_id":{"source":"2019-03-24","status":false},"count":2},
{"_id":{"source":"2019-03-24","status":true},"count":1},
{"_id":{"source":"2019-03-23","status":false},"count":3},
{"_id":{"source":"2019-03-08","status":false},"count":1},
{"_id":{"source":"2019-02-02","status":true},"count":1},
{"_id":{"source":"2019-02-02","status":false},"count":2},
{"_id":{"source":"2019-01-29","status":false},"count":1},
];
const byDate = {};
data.forEach((f, ndx) => {
byDate[f._id.source] = byDate[f._id.source] || [];
byDate[f._id.source].push(f);
});
function mapCounts(byDate, status) {
return Object.values(byDate).map(d => {
return d.reduce((acc, e) => acc + (e._id.status === status ? e.count : 0), 0);
});
}
const falseForDate = mapCounts(byDate, false);
const trueForDate = mapCounts(byDate, true);
console.log(falseForDate.join(','));
console.log(trueForDate.join(','));
or
const data = [
{"_id":{"source":"2019-04-06","status":false},"count":1},
{"_id":{"source":"2019-04-06","status":true},"count":1},
{"_id":{"source":"2019-03-24","status":false},"count":2},
{"_id":{"source":"2019-03-24","status":true},"count":1},
{"_id":{"source":"2019-03-23","status":false},"count":3},
{"_id":{"source":"2019-03-08","status":false},"count":1},
{"_id":{"source":"2019-02-02","status":true},"count":1},
{"_id":{"source":"2019-02-02","status":false},"count":2},
{"_id":{"source":"2019-01-29","status":false},"count":1},
];
const byDate = {};
data.forEach((f, ndx) => {
byDate[f._id.source] = byDate[f._id.source] || [0, 0];
byDate[f._id.source][f._id.status === true ? 1 : 0] += f.count;
});
const falseForDate = Object.values(byDate).map(v => v[0]);
const trueForDate = Object.values(byDate).map(v => v[1]);
console.log(falseForDate.join(','));
console.log(trueForDate.join(','));
You can use map to achieve this. They key of the map will be the source and value will be count. If no value found for a particular key, then assign 0. Otherwise assign value based on the given condition.
Iterate over all elements of inputArray. After the end of iteration, you will get two objects. Just take the values of the objects using Object.values() function.
You're done!!!
I have used ternary operator to make the code look short and easy. See the snippet below
var inputArray = [{"_id":{"source":"2019-04-06","status":false},"count":1},{"_id":{"source":"2019-04-06","status":true},"count":1},{"_id":{"source":"2019-03-24","status":false},"count":2},{"_id":{"source":"2019-03-24","status":true},"count":1},{"_id":{"source":"2019-03-23","status":false},"count":3},{"_id":{"source":"2019-03-08","status":false},"count":1},{"_id":{"source":"2019-02-02","status":true},"count":1},{"_id":{"source":"2019-02-02","status":false},"count":2},{"_id":{"source":"2019-01-29","status":false},"count":1}];
var trueObjects = {},
falseObjects = {};
inputArray.forEach(function(elem) {
var index = elem._id.source,
status = elem._id.status,
count = elem.count;
//initialize value for new index
trueObjects[index] = trueObjects[index] ? trueObjects[index] : 0;
falseObjects[index] = falseObjects[index] ? falseObjects[index] : 0;
//set value based on condition
trueObjects[index] = status ? count : trueObjects[index];
falseObjects[index] = !status ? count : falseObjects[index];
});
trueArray = Object.values(trueObjects);
falseArray = Object.values(falseObjects);
console.log(falseArray);
console.log(trueArray);
You can get unique sources (dates) and create true and false arrays for each source :
const dataArray = [{"_id":{"source":"2019-04-06","status":false},"count":1},
{"_id":{"source":"2019-04-06","status":true},"count":1},
{"_id":{"source":"2019-03-24","status":false},"count":2},
{"_id":{"source":"2019-03-24","status":true},"count":1},
{"_id":{"source":"2019-03-23","status":false},"count":3},
{"_id":{"source":"2019-03-08","status":false},"count":1},
{"_id":{"source":"2019-02-02","status":true},"count":1},
{"_id":{"source":"2019-02-02","status":false},"count":2},
{"_id":{"source":"2019-01-29","status":false},"count":1}];
// Get all sources
const sources = dataArray.map(item => item._id.source);
// Get unique sources
const uniqueSources = [...(new Set(sources))];
const arrayForStatusTrue = [];
const arrayForStatusFalse = [];
uniqueSources.forEach(source => {
// Check if source with status true exists
const itemWithStatusTrue = dataArray.find(item => (item._id.status && item._id.source === source));
itemWithStatusTrue ? arrayForStatusTrue.push(itemWithStatusTrue.count) : arrayForStatusTrue.push(0);
// Check if source with status false exists
const itemWithStatusFalse = dataArray.find(item => (!item._id.status && item._id.source === source));
itemWithStatusFalse ? arrayForStatusFalse.push(itemWithStatusFalse.count) : arrayForStatusFalse.push(0);
});
console.log(arrayForStatusTrue);
console.log(arrayForStatusFalse);
I would suggest using a Map to create one entry per date (source), which each would have two values representing the counts for both possible statuses (initialised with zero).
Then add the actual counts to those entries, and finally extract the data into the two arrays you expect:
// Sample input
const array = [{ _id: { source: "2019-04-06", status: false }, count: 1 }, { _id: { source: "2019-04-06", status: true }, count: 1 }, { _id: { source: "2019-03-24", status: false }, count: 2 }, { _id: { source: "2019-03-24", status: true }, count: 1 }, { _id: { source: "2019-03-23", status: false }, count: 3 }, { _id: { source: "2019-03-08", status: false }, count: 1 }, { _id: { source: "2019-02-02", status: true }, count: 1 }, { _id: { source: "2019-02-02", status: false }, count: 2 }, { _id: { source: "2019-01-29", status: false }, count: 1 }];
// Algorithm
const map = new Map(array.map(o => [o._id.source, [0,0]]));
array.forEach(o => map.get(o._id.source)[+o._id.status] += o.count);
const [noes, ayes] = [0, 1].map(i => Array.from(map.values(), a => a[i]));
// Output
console.log(JSON.stringify(noes), JSON.stringify(ayes));

JS findIndex method always returns -1

This:
const pageID: number = 4;
and this:
this.charts.findIndex((chart: IChart) => {
return chart.pageID === pageID;
}));
this.charts is an array of IChart[] which contains:
[
{
"pageID": 3,
"zoomable": false
},
{
"pageID": 4,
"zoomable": false
},
{
"pageID": 5,
"zoomable": false
}
]
Amazingly, this always returns -1. Even if I change the value of pageID to 4 or 5.
Usually this works, but it's driving me nuts. The only thing I am doing before trying to find the index is merging two arrays and removing duplicate values based on the pageID parameter, like this:
let unique = {};
this.charts = charts[0].concat(charts[1])
.filter((chart) => !unique[chart.pageID] && (unique[chart.pageID] = true))
.sort((a, b) => a.pageID - b.pageID);
The output of this.charts is the array pasted above with zoomable and pageID properties.
--
It's not rocket science even running the above in the proper sequence inside node returns the proper index which is 1 in my case. Does anyone have any insights on this issue?
Note: this is running in a Cordova app on iOS wkwebview.
Thank you.
Your code seems to run just fine.
const allCharts = [[
{ 'pageID': 3, 'zoomable': false },
{ 'pageID': 4, 'zoomable': false },
{ 'pageID': 5, 'zoomable': false }
], [
{ 'pageID': 3, 'zoomable': false },
{ 'pageID': 6, 'zoomable': false },
{ 'pageID': 7, 'zoomable': false }
]];
let unique = {};
const charts = allCharts[0].concat(allCharts[1])
.filter(chart => !unique[chart.pageID] && (unique[chart.pageID] = true))
.sort((a, b) => a.pageID - b.pageID);
const pageID = 4;
const idx = charts.findIndex(chart => {
return chart.pageID === pageID;
});
console.log(JSON.stringify(charts));
console.log('idx of pageId 4 is:', idx);

How to automatically insert comma or ampersand in between words in JS based on boolean?

const confirmations = {
quantity: false,
total_price: true,
unit_price: true
}
// Should print -> Total Price & Unit Price
// If three variables are true then should print -> Quantity, Total Price & Unit Price
I know this can be achieved using couple of if...else statements but that's really lame. Is there other way to achieve this?
You could take another object for wording and then create a nice string by replacing the last two words with an ampersand and all words before join with comma.
function getString(confirmations) {
const
nice = a => a.concat(a.splice(-2, 2).join(' & ')).join(', '),
words = { quantity: 'Quantity', total_price: 'Total Price', unit_price: 'Unit Price' };
return nice(Object
.entries(confirmations)
.filter(([, v]) => v)
.map(([w]) => words[w])
);
}
console.log(getString({ quantity: false, total_price: true, unit_price: true }));
console.log(getString({ quantity: true, total_price: true, unit_price: true }));
console.log(getString({ quantity: false, total_price: true, unit_price: false }));
You can do:
const confirmations1 = {quantity: false, total_price: true, unit_price: true};
const confirmations2 = {quantity: true, total_price: true, unit_price: true};
const getFormattedSentence = obj => Object
.keys(obj)
.filter(k => obj[k])
.map(k => k
.split('_')
.map(w => w.charAt(0).toUpperCase() + w.slice(1))
.join(' ')
)
.join(', ')
.replace(/,(?!.*,)/gmi, ' &');
console.log(getFormattedSentence(confirmations1));
console.log(getFormattedSentence(confirmations2));
Here is my attempt. Much slimmer after studying Yosvel Quintero's version
const fmtText = obj => Object
.keys(obj) // array of keys
.filter(k => obj[k]) // take only the true ones
.join(", ") // join found keys with ,
.replace(/_/g, " ") // replace the underscore
.replace(/\b([a-z])/g, x => x.toUpperCase()) // InitialCap
.replace(/,(?=[^,]*$)/, ' &'); // replace last comma
const conf1 = { quantity: false, total_price: true, unit_price: true }
const conf2 = { quantity: true, total_price: true, unit_price: true }
const conf3 = { quantity: false, total_price: true, unit_price: false }
console.log(fmtText(conf1))
console.log(fmtText(conf2))
console.log(fmtText(conf3))
This should do the job :
const confirmations = {
quantity: false,
total_price: true,
unit_price: true
};
// filter out false values and return object keys as an array of strings
const validatedConfirmations = Object.keys(confirmations).filter((name) => confirmations[name]);
// make them human readable
const humanReadableConfirmations = validatedConfirmations.map(makeItHumanReadable);
// crunch it all to a single string
const lastConfirmationMessage = humanReadableConfirmations.pop();
const confirmationMessage = humanReadableConfirmation.join(', ') + ` & ${lastConfirmationMessage}`;
Careful, if only one element is true, it will display "& Unit Price", you can adapt it anyway.

Categories

Resources