如何根据嵌套数组元素对对象进行排序

时间:2020-10-07 12:47:43

标签: javascript node.js

我需要按创建最早的帐户对主要数据进行排序。 在下面的示例中,列表中的第一个元素为id =2。这是因为id = 2包含创建的最早帐户(名为account3,该帐户创建于2020-10-05,而其他帐户则是在创建之后该日期)。 我正在使用nodejs。是否存在可以轻松解决此问题的es函数?

对象数据如下:

{
  "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"
      }
    }]
  }]
}

2 个答案:

答案 0 :(得分:1)

您通常可以使用map-> sort-> map解决此问题。 它在输入上进行了3次传递,但仍为O(n log n)。您可以进一步优化,但是我怀疑这会成为瓶颈。

  1. 映射到[record, oldestAccountDate]元组。

  2. oldestAccountDate对元组进行排序。

  3. 再次映射以解开记录。

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);

答案 1 :(得分: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);