0

I need to sort the main data by the oldest created account. In the example below, the first element in the list would be id = 2. That's because the id = 2 contains the oldest created account (named account3, which was created at 2020-10-05, while the other accounts have been created after that date). I'm using nodejs. Is there an es-function that can solve this problem in an easy way?

The object data looks like this:

{
  "data": [{
    "id": 1,
    "accounts": [{
      "id": 333,
      "data": {
        "name": "account1",
        "createdAt": "2020-10-07T09:27:28.032Z"
      }
    }]
  }, {
    "id": 2,
    "accounts": [{
      "id": 334,
      "data": {
        "name": "account2",
        "createdAt": "2020-10-06T09:27:28.032Z"
      }
    }, {
      "id": 335,
      "data": {
        "name": "account3",
        "createdAt": "2020-10-05T09:27:28.032Z"
      }
    }]
  }]
}

5
  • 2
    Please take a look at How to Ask and produce a minimal reproducible example of your effort with expected output Commented Oct 7, 2020 at 12:50
  • 1
    it would be better if you fetch this data sorted from your database it would be more efficient Commented Oct 7, 2020 at 12:50
  • Data is in elasticsearch. I wanted to avoid to sort it there because Im afraid I would need to use painless-script to achieve that, which is also quite difficult. Commented Oct 7, 2020 at 12:53
  • Also you have a data element and two other array elements Commented Oct 7, 2020 at 12:53
  • Yes but it is the way it looks. Commented Oct 7, 2020 at 12:54

2 Answers 2

1

You can often solve this problem with map --> sort --> map. It does 3 passes on the input but remains O(n log n). You could further optimize, but I doubt this becomes a bottleneck.

  1. Map to [record, oldestAccountDate] tuples.

  2. Sort the tuples by oldestAccountDate.

  3. Map again to unwrap the record.

const wrapper = {
  "data": [{
    "id": 1,
    "accounts": [{
      "id": 333,
      "data": {
        "name": "account1",
        "createdAt": "2020-10-07T09:27:28.032Z"
      }
    }]
  }, {
    "id": 2,
    "accounts": [{
      "id": 334,
      "data": {
        "name": "account2",
        "createdAt": "2020-10-06T09:27:28.032Z"
      }
    }, {
      "id": 335,
      "data": {
        "name": "account3",
        "createdAt": "2020-10-05T09:27:28.032Z"
      }
    }]
  }]
};

wrapper.data = wrapper.data
  .map(rec => [rec, Math.min(...rec.accounts.map(acc => new Date(acc.data.createdAt)))])
  .sort((a, b) => a[1] - b[1])
  .map(tuple => tuple[0]);
  
  
 console.log(wrapper);

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

Comments

1

const data = [{
  "id": 1,
  "accounts": [{
    "id": 333,
    "data": {
      "name": "account1",
      "createdAt": "2020-10-07T09:27:28.032Z"
    }
  }]
}, {
  "id": 2,
  "accounts": [{
    "id": 334,
    "data": {
      "name": "account2",
      "createdAt": "2020-10-06T09:27:28.032Z"
    }
  }, {
    "id": 335,
    "data": {
      "name": "account3",
      "createdAt": "2020-10-05T09:27:28.032Z"
    }
  }]
}]

const sorted = data.sort((a, b) => {
  const aOldestDate = a.accounts.reduce((acc, item) => {
    const itemDate = new Date(item.data.createdAt);
    return itemDate < acc && itemDate || acc;
  }, new Date());
  
  const bOldestDate = b.accounts.reduce((acc, item) => {
    const itemDate = new Date(item.data.createdAt);
    return itemDate < acc && itemDate || acc;
  }, new Date());
  
  return aOldestDate - bOldestDate;
});

console.log(sorted);

2 Comments

You can do that but it becomes O(n * n log n) complexity because you re-resolve the oldest account for every compare.
@plalx, thank you very much for your comment. I am a self-thought developer with no formal education in CS; many "theoretical" arguments like algorithms complexity are not (yet) something I am familiar with. That is a topic I'll have to learn sooner rather than later. :)

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.