0

I am using lodash.orderBy method and try to sort data like this:

I have two external sort conditions: condition1 and condition2

const condition1 = 'aa';
const condition2 = 'b';

const datas = [
  { f1: 'aaa', f2: 'b', f3: '2019-01-01' },
  { f1: 'a', f2: 'b', f3: '2019-01-02' },
  { f1: 'a', f2: 'c', f3: '2019-01-08' },
  { f1: 'aa', f2: 'b', f3: '2019-01-08' },
  { f1: 'aa', f2: 'b', f3: '2019-01-09' },
  { f1: 'aa', f2: 'c', f3: '2019-01-07' },
  { f1: 'xxx', f2: 'c', f3: '2019-01-03' },
  { f1: 't', f2: 'd', f3: '2019-01-04' },
  { f1: 'a', f2: 'd', f3: '2019-01-01' },
  { f1: 'aa', f2: 'd', f3: '2019-01-02' },
];

I expect data sorted like this:

  const expect = [
          { f1: 'aa', f2: 'b', f3: '2019-01-09' },
          { f1: 'aa', f2: 'b', f3: '2019-01-08' },
          { f1: 'aa', f2: 'c', f3: '2019-01-07' },
          { f1: 'aa', f2: 'd', f3: '2019-01-02' },
          { f1: 'a', f2: 'b', f3: '2019-01-02' },
          { f1: 'aaa', f2: 'b', f3: '2019-01-01' },
          { f1: 'a', f2: 'c', f3: '2019-01-08' },
          { f1: 't', f2: 'd', f3: '2019-01-04' },
          { f1: 'xxx', f2: 'c', f3: '2019-01-03' },
          { f1: 'a', f2: 'd', f3: '2019-01-01' },
        ];

The sorting rule is:

  1. sort by f1 if the value of f1 equal with condition1 - priority 1
  2. sort by f2 if f1 is same, the value of f2 should equal with condition2 - priority 2
  3. sort by f3(desc) when f1 and f2 are same - priority 3

priority 1 is the highest.

Can't figure it out. Thanks for your help. lodash.orderBy and sort method of javascript, both of these solutions are ok.

2 Answers 2

1

I’m not sure I fully understand your problem, but it looks to me as if the JavaScript sort function combined with a custom sort function is all you need.

Something like this (not tested) code:

datas.sort(function(a, b) {
  if (a.f1 === condition1) {
    return a.f1.localeCompare(b.f1);
  } else if (a.f2 === condition2) {
    return a.f2.localeCompare(b.f2);
  } else {
    return a.f3.localeCompare(b.f3);
  }
});
Sign up to request clarification or add additional context in comments.

3 Comments

If performance is an issue, you may want to create a collator. See my answer here: stackoverflow.com/a/38641281/2095953
Thanks. But the unit test doesn't pass. I improve my question.
@slideshowp2 I see. This only makes the If a little more complicated and instead of just returning from the string compare, just must go a level deeper if the strings are the same and do the next if.
0

I found a solution but it looks like very verbose.

it('t1', () => {
        const goal = 'aa';
        const channelNme = 'b';

        const datas = [
          { goal: 'aaa', channelNme: 'b', date: '2019-01-01' },
          { goal: 'a', channelNme: 'b', date: '2019-01-02' },
          { goal: 'a', channelNme: 'c', date: '2019-01-08' },
          { goal: 'aa', channelNme: 'b', date: '2019-01-08' },
          { goal: 'aa', channelNme: 'b', date: '2019-01-09' },
          { goal: 'aa', channelNme: 'c', date: '2019-01-07' },
          { goal: 'xxx', channelNme: 'c', date: '2019-01-03' },
          { goal: 't', channelNme: 'd', date: '2019-01-04' },
          { goal: 'a', channelNme: 'd', date: '2019-01-01' },
          { goal: 'aa', channelNme: 'd', date: '2019-01-02' },
        ];

        const aa = datas.filter(d => d.goal === goal).sort(sortByDateDesc);
        const notAa = datas.filter(d => d.goal !== goal).sort(sortByDateDesc);
        const notAaB = notAa.filter(d => d.channelNme === channelNme).sort(sortByDateDesc);
        const notAaNotB = notAa.filter(d => d.channelNme !== channelNme).sort(sortByDateDesc);

        const actualValue = [...aa, ...notAaB, ...notAaNotB];

        function sortByDateDesc(a, b) {
          return new Date(b.date).getTime() - new Date(a.date).getTime();
        }

        const expectValue = [
          { goal: 'aa', channelNme: 'b', date: '2019-01-09' },
          { goal: 'aa', channelNme: 'b', date: '2019-01-08' },
          { goal: 'aa', channelNme: 'c', date: '2019-01-07' },
          { goal: 'aa', channelNme: 'd', date: '2019-01-02' },
          { goal: 'a', channelNme: 'b', date: '2019-01-02' },
          { goal: 'aaa', channelNme: 'b', date: '2019-01-01' },
          { goal: 'a', channelNme: 'c', date: '2019-01-08' },
          { goal: 't', channelNme: 'd', date: '2019-01-04' },
          { goal: 'xxx', channelNme: 'c', date: '2019-01-03' },
          { goal: 'a', channelNme: 'd', date: '2019-01-01' },
        ];
        console.log(`actualValue: ${JSON.stringify(actualValue, null, 2)}`);
        expect(actualValue).toEqual(expectValue);
      });

This unit test passed. Hope there is a better way.

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.