Reputation: 361
I have the following array of objects:
Update: full code
export const fetchInvoices = function (firestore, currentUser) {
const db = firestore
.collection("customers")
.doc(currentUser)
.collection("subscriptions");
let invoices = [];
db.get().then((subscriptionSnapshot) => {
subscriptionSnapshot.forEach((doc) => {
doc.ref.collection("invoices").get().then((invoiceSnapshot) => {
invoiceSnapshot.forEach(async (doc) => {
let invoice = {
"billing_reason": doc.data().billing_reason,
"created": doc.data().created,
"currency": doc.data().currency,
"hosted_invoice_url": doc.data().hosted_invoice_url,
"id": doc.id,
"invoice_pdf": doc.data().invoice_pdf,
"number": doc.data().number,
"period_end": doc.data().period_end,
"period_start": doc.data().period_start,
"status": doc.data().status,
"subtotal": doc.data().subtotal,
"total": doc.data().total
};
Object.defineProperty(invoice, 'invoice_id', { value: doc.id });
invoices.push(invoice);
})
})
});
});
const sortedData = invoices.sort((a, b) => +(b.status === 'open') - +(a.status === 'open'));
console.log(sortedData);
return sortedData;
}
I want to sort them by the ones with status: "open"
on the first indexes, and then sort by created
. Is there a way to do this?
I've been trying to sort only the group of status: "open"
using Object.values(obj).includes("open")
to determine if the object has the value and then sort by truth
as here.
But still can't even make this "sort by group".
Upvotes: 0
Views: 118
Reputation: 12920
Sorting by two different criteria is simply a matter of chaining your criteria with logical OR (||).
In the first example, first by data.status
converting boolean to an integer and then by data.created
.
const data = [ { "created": 1, "status": "draft", }, { "created": 5, "status": "paid", }, { "created": 2, "status": "open", }, { "created": 6, "status": "paid", }, { "created": 3, "status": "open", }, { "created": 4, "status": "paid", }, ];
const sortedData = data
.sort((a, b) => +(b.status === 'open') - +(a.status === 'open') || a.created - b.created);
console.log(sortedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
or, since you have multiple status
values, you can create a sortOrder
map and reference it in your sort callback.
const data = [ { "created": 1, "status": "draft", }, { "created": 5, "status": "paid", }, { "created": 2, "status": "open", }, { "created": 6, "status": "paid", }, { "created": 3, "status": "open", }, { "created": 4, "status": "paid", }, ];
const sortOrder = {
open: 1,
paid: 2,
draft: 3
}
const sortedData = data
.sort((a, b) => sortOrder[a.status] - sortOrder[b.status] || a.created - b.created);
console.log(sortedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 839
If you're open to using some great libraries out there this solution might work for you using underscore which is great for situations like this.
Assuming you put your original array into a variable called data
as in Solvenc1no's answer :
const _ = require('underscore');
const sortedAndGrouped = _.groupBy(_.sortBy(data, "created"),'status');
console.log(sortedAndGrouped);
Which results in this output:
{ draft:
[ { billing_reason: 'subscription_create',
created: 1614889156,
currency: 'usd',
hosted_invoice_url: '...',
id: '...',
invoice_pdf: '...',
number: '82190D09-0001',
period_end: 1614889156,
period_start: 1614889156,
status: 'draft',
subtotal: 3900,
total: 3900 } ],
paid:
[ { billing_reason: 'subscription_cycle',
created: 1614890009,
currency: 'usd',
hosted_invoice_url: '...',
id: '...',
invoice_pdf: '...',
number: '82190D09-0002',
period_end: 1614890009,
period_start: 1614890009,
status: 'paid',
subtotal: 3900,
total: 3900 },
{ billing_reason: 'subscription_create',
created: 1614890802,
currency: 'usd',
hosted_invoice_url: '...',
id: '...',
invoice_pdf: '...',
number: '82190D09-0004',
period_end: 1614890802,
period_start: 1614890802,
status: 'paid',
subtotal: 3900,
total: 3900 },
{ billing_reason: 'subscription_create',
created: 1614892003,
currency: 'usd',
hosted_invoice_url: '...',
id: '...',
invoice_pdf: '...',
number: '82190D09-0005',
period_end: 1614892002,
period_start: 1614892002,
status: 'paid',
subtotal: 3900,
total: 3900 },
{ billing_reason: 'subscription_create',
created: 1614893124,
currency: 'usd',
hosted_invoice_url: '...',
id: '...',
invoice_pdf: '...',
number: '82190D09-0006',
period_end: 1614893124,
period_start: 1614893124,
status: 'paid',
subtotal: 3900,
total: 3900 } ],
open:
[ { billing_reason: 'subscription_update',
created: 1614890064,
currency: 'usd',
hosted_invoice_url: '...',
id: '...',
invoice_pdf: '...',
number: '82190D09-0003',
period_end: 1614890064,
period_start: 1614890009,
status: 'open',
subtotal: -1400,
total: -1400 } ] }
Upvotes: 0
Reputation: 660
You can get objects with open status using filter method and sort them using sort method like this.
You can change the order of sort by returning value accordingly in sort function.
const data = [
{
"billing_reason": "subscription_create",
"created": 1614889156,
"currency": "usd",
"hosted_invoice_url": "...",
"id": "...",
"invoice_pdf": "...",
"number": "82190D09-0001",
"period_end": 1614889156,
"period_start": 1614889156,
"status": "draft",
"subtotal": 3900,
"total": 3900
},
{
"billing_reason": "subscription_cycle",
"created": 1614890009,
"currency": "usd",
"hosted_invoice_url": "...",
"id": "...",
"invoice_pdf": "...",
"number": "82190D09-0002",
"period_end": 1614890009,
"period_start": 1614890009,
"status": "paid",
"subtotal": 3900,
"total": 3900
},
{
"billing_reason": "subscription_update",
"created": 1614890064,
"currency": "usd",
"hosted_invoice_url": "...",
"id": "...",
"invoice_pdf": "...",
"number": "82190D09-0003",
"period_end": 1614890064,
"period_start": 1614890009,
"status": "open",
"subtotal": -1400,
"total": -1400
},
{
"billing_reason": "subscription_create",
"created": 1614890802,
"currency": "usd",
"hosted_invoice_url": "...",
"id": "...",
"invoice_pdf": "...",
"number": "82190D09-0004",
"period_end": 1614890802,
"period_start": 1614890802,
"status": "paid",
"subtotal": 3900,
"total": 3900
},
{
"billing_reason": "subscription_create",
"created": 1614892003,
"currency": "usd",
"hosted_invoice_url": "...",
"id": "...",
"invoice_pdf": "...",
"number": "82190D09-0005",
"period_end": 1614892002,
"period_start": 1614892002,
"status": "paid",
"subtotal": 3900,
"total": 3900
},
{
"billing_reason": "subscription_create",
"created": 1614893124,
"currency": "usd",
"hosted_invoice_url": "...",
"id": "...",
"invoice_pdf": "...",
"number": "82190D09-0006",
"period_end": 1614893124,
"period_start": 1614893124,
"status": "paid",
"subtotal": 3900,
"total": 3900
},
]
const open = data.filter(d => d.status === "open").sort((a,b) => a.created - b.created);
console.log(open);
Upvotes: 0