2

So I have an array of statuses and I want to get distinct values based on an element property ProductOrderStatusTypeID. I have one implementation but I want the cleanest way of doing that.

My list:

[{
  StatusID : 1,
  Name : "Open",
  ProductOrderStatusType : 'Initial'
  ProductOrderStatusTypeID : 1
},{
  StatusID : 3,
  Name : "Closed",
  ProductOrderStatusType : 'Final'
  ProductOrderStatusTypeID : 2
},
{
  StatusID : 3,
  Name : "Pending",
  ProductOrderStatusType : 'Initial'
  ProductOrderStatusTypeID : 1
}]

Expected output:

[{
  ProductOrderStatusType : 'Initial',
  ProductOrderStatusTypeID : 1
},{
  ProductOrderStatusType : 'Final',
  ProductOrderStatusTypeID : 2
}]

My code:

function getDistinctProductOrderStatusType(statuses) {
    return statuses.reduce(function (result, status) {
        var existingStatus = result.filter(function (res) {
            return res.ProductOrderStatusTypeID === status.ProductOrderStatusTypeID;
        })[0];
        if (!existingStatus) {
            result.push({
                ProductOrderStatusTypeID: status.ProductOrderStatusTypeID,
                ProductOrderStatusType: status.ProductOrderStatusType
            });
        }
        return result;
    }, []);
}
5
  • 9
    Probably best suited for codereview.stackexchange.com - since your code works but you want a suggestion to make it different. Commented Jul 16, 2019 at 20:12
  • Make sense guys thanks . i will post it there Commented Jul 16, 2019 at 20:22
  • 2
    Reducing to an object or Map using the "groupBy" values as keys is a lot more efficient than running filter() each iteration... then get values from that object Commented Jul 16, 2019 at 20:26
  • Statuses is array that i have mentioned in my question as 'My List' Commented Jul 16, 2019 at 20:29
  • @charlietfl any suggestions ? Commented Jul 16, 2019 at 20:32

1 Answer 1

2

const stat = [{
    StatusID: 1,
    Name: "Open",
    type: 'Initial', // !!! I renamed properties for simplicity sake
    typeID: 1
  }, {
    StatusID: 3,
    Name: "Closed",
    type: 'Final',
    typeID: 2
  }, {
    StatusID: 3,
    Name: "Pending",
    type: 'Initial',
    typeID: 1
  }
];

const distinctStat = arr => arr.reduce((a, {type, typeID}) =>
  a.some(ob => ob.typeID === typeID) ? a : a.concat({type, typeID})
, []);

console.log( distinctStat(stat) );

In case you find it more easier to name the properties you're not interested in collecting (like i.y.e: StatusID and Name) than you could go for the rest element:

const distinctStat = arr => arr.reduce((a, {StatusID, Name, ...r}) =>
  a.some(ob => ob.typeID === r.typeID) ? a : a.concat(r)
, []);

(same output as above)

Info:

Although we could, in the above code Array.prototype.some() is used instead of Array.prototype.find() because we don't need to return the entire object but just a boolean (as quickly as possible).

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

Comments

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.