Home > database >  Retuning a single array object value from the map function on a ternary condition. Problem is it ret
Retuning a single array object value from the map function on a ternary condition. Problem is it ret

Time:12-04

Here is a code snippet i want to return the supplier id on a condition if at date is less than or equal to rounddate then it should return the supplier ID

const currentRound = 0;
const roundDate = new Date('2021-12-02T10:41:57.133Z');
const offers = [
    {
        by: 'supplier',
        user_Id: '46a065f05229450e805a0a38d94b0956',
        supplier_id: '7a444fea780d90ddc7c35e09104c73b0',
        total: 14700,
        round: 0,
        at: '2021-12-01T10:46:52.278Z',
    },
    {
        by: 'supplier',
        user_Id: '6fb6562bd52fd70b3f43aea1da76de16',
        supplier_id: 'abc7c8e6b5acc1888ebf5d2398c44d0b',
        total: 14800,
        round: 0,
        at: '2021-12-03T04:59:45.137Z',
    },
];

const suppliersWhoSubmitBid = offers.map((e) =>
  e.round === currentRound && new Date(e.at) <= roundDate && e.supplier_id
);

expected result = [ '7a444fea780d90ddc7c35e09104c73b0' ]

actual result = [ '7a444fea780d90ddc7c35e09104c73b0', false]

CodePudding user response:

When you're not producing a result for every input, that's not a mapping operation, it's a filtering operation (followed, in this case, by a mapping operation). So you'd use filter, then map:

const suppliersWhoSubmitBid = offers
    .filter(e => e.round === currentRound && new Date(e.at) <= roundDate)
    .map(e => e.supplier_id);

Live Example:

Show code snippet

const currentRound = 0;
const roundDate = new Date("2021-12-02T10:41:57.133Z");
const offers = [
    {
        by: "supplier",
        user_Id: "46a065f05229450e805a0a38d94b0956",
        supplier_id: "7a444fea780d90ddc7c35e09104c73b0",
        total: 14700,
        round: 0,
        at: "2021-12-01T10:46:52.278Z"
    },
    {
        by: "supplier",
        user_Id: "6fb6562bd52fd70b3f43aea1da76de16",
        supplier_id: "abc7c8e6b5acc1888ebf5d2398c44d0b",
        total: 14800,
        round: 0,
        at: "2021-12-03T04:59:45.137Z",
    }
];

const suppliersWhoSubmitBid = offers
  .filter(e => e.round === currentRound && new Date(e.at) <= roundDate)
  .map(e => e.supplier_id);

console.log(suppliersWhoSubmitBid);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Or, if the array was really large or just for style reasons, you could use a loop to make one pass rather than two:

const suppliersWhoSubmitBid = [];
for (const e of offers) {
    if (e.round === currentRound && new Date(e.at) <= roundDate) {
        suppliersWhoSubmitBid.push(e.supplier_id);
    }
}

Live Example:

Show code snippet

const currentRound = 0;
const roundDate = new Date("2021-12-02T10:41:57.133Z");
const offers = [
    {
        by: "supplier",
        user_Id: "46a065f05229450e805a0a38d94b0956",
        supplier_id: "7a444fea780d90ddc7c35e09104c73b0",
        total: 14700,
        round: 0,
        at: "2021-12-01T10:46:52.278Z"
    },
    {
        by: "supplier",
        user_Id: "6fb6562bd52fd70b3f43aea1da76de16",
        supplier_id: "abc7c8e6b5acc1888ebf5d2398c44d0b",
        total: 14800,
        round: 0,
        at: "2021-12-03T04:59:45.137Z",
    }
];

const suppliersWhoSubmitBid = [];
for (const e of offers) {
    if (e.round === currentRound && new Date(e.at) <= roundDate) {
        suppliersWhoSubmitBid.push(e.supplier_id);
    }
}

console.log(suppliersWhoSubmitBid);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>


Just for completeness: In JavaScript code we're sort of used to dealing with arrays of things, but JavaScript has had iterables and iterators as a first-class concept since ES2015 and this kind of combined operation is where iterability can be really useful. Suppose you have two reusable utility generator functions:

function* filter(iterable, predicate) {
    for (const entry of iterable) {
        if (predicate(entry)) {
            yield entry;
        }
    }
}
function* map(iterable, mapper) {
    for (const entry of iterable) {
        yield mapper(entry);
    }
}

They both take iterables (like arrays). The first yields (produces) only entries the predicate function returns a truthy value for, and the second yields a mapped/transformed value. We could then use it to produce an iterable of matching supplier IDs:

const suppliersWhoSubmitBidIterable = map(
    filter(offers, e => e.round === currentRound && new Date(e.at) <= roundDate),
    e => e.supplier_id
);

Or if the end result has to be an array, we spread the iterable out into an array:

const suppliersWhoSubmitBid = [...map(
    filter(offers, e => e.round === currentRound && new Date(e.at) <= roundDate),
    e => e.supplier_id
)];

Live Example:

Show code snippet

const currentRound = 0;
const roundDate = new Date("2021-12-02T10:41:57.133Z");
const offers = [
    {
        by: "supplier",
        user_Id: "46a065f05229450e805a0a38d94b0956",
        supplier_id: "7a444fea780d90ddc7c35e09104c73b0",
        total: 14700,
        round: 0,
        at: "2021-12-01T10:46:52.278Z"
    },
    {
        by: "supplier",
        user_Id: "6fb6562bd52fd70b3f43aea1da76de16",
        supplier_id: "abc7c8e6b5acc1888ebf5d2398c44d0b",
        total: 14800,
        round: 0,
        at: "2021-12-03T04:59:45.137Z",
    }
];

function* filter(iterable, predicate) {
    for (const entry of iterable) {
        if (predicate(entry)) {
            yield entry;
        }
    }
}
function* map(iterable, mapper) {
    for (const entry of iterable) {
        yield mapper(entry);
    }
}

const suppliersWhoSubmitBid = [...map(
    filter(offers, e => e.round === currentRound && new Date(e.at) <= roundDate),
    e => e.supplier_id
)];

console.log(suppliersWhoSubmitBid);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related