【问题标题】:Object/Array manipulation [closed]对象/数组操作[关闭]
【发布时间】:2017-02-16 05:51:39
【问题描述】:

我从 db 查询(nodejs,使用带有 Knex 的 Postgres)中得到一个 对象数组,如下所示:(缩小版)

[ 
   {
    tvshow: 'house',
    airdate: 2017-02-01T00:00:00.000Z 
   },
   {
    tvshow: 'big bang theory',
    airdate: 2017-02-01T00:00:00.000Z 
   },
   {
    tvshow: 'simpsons',
    airdate: 2017-02-02T00:00:00.000Z 
   },
   {
    tvshow: 'suits',
    airdate: 2017-02-02T00:00:00.000Z 
   },
   {
    tvshow: 'sun',
    airdate: 2017-02-03T00:00:00.000Z 
   },
   {
    tvshow: 'blacklist',
    airdate: 2017-02-03T00:00:00.000Z
  },
  {
    tvshow: 'something',
    airdate: 2017-02-03T00:00:00.000Z 
  },
  {
    tvshow: 'homeland',
    airdate: 2017-02-03T00:00:00.000Z 
  },
  {
    tvshow: 'american dad',
    airdate: 2017-02-04T00:00:00.000Z 
  },
  {
    tvshow: 'games',
    airdate: 2017-02-05T00:00:00.000Z 
  }
]

返回此内容的查询将 airdate 字段限制为 5 天。这意味着无论我用它做什么,它都会总是有 5 天

我的目标是按天过滤电视节目

预期输出示例

{
    day1: [ 'house', 'big bang theory' ],
    day2: [ 'simpsons', 'suits' ],
    day3: [ 'sun', 'blacklist', 'something', 'homeland' ],
    day4: [ 'american dad' ],
    day5: [ 'games' ]
}

我有一个可行的解决方案,但我认为它可以改进。这就是我正在做的自动取款机。我正在使用 momentjs 来比较日期。 'result' 是查询结果的名称(对象数组)。

const obj = {};
let array = [];
let i = 0;
let currentDate = null;

result.forEach((element) => {
  if (currentDate !== moment(element.airdate).format('DD-MM-YYYY')) {
    if (currentDate !== null) {      // skip first iteration where currentDate is null
      i++;
      obj[`day${i}`] = array;     // new day => store previous day tvshow's array in the object
    }
    array = [];     // reset temporary array
  }
  array.push(element.tvshow);    // push tvshow to temporary array
  currentDate = moment(element.airdate).format('DD-MM-YYYY');   // update current date
});
obj[`day${i+1}`] = array;    // add last/5th day array to the object

【问题讨论】:

  • 你还没有问过问题。
  • “我有一个可行的解决方案,但我认为它可以改进。” Stack Overflow 主要针对的代码问题工作。 codereview.stackexchange.com 可能是您提出问题的更好地方,但您还需要更具体。
  • @HunterMcMillen 对不起,如果我不够清楚。问题是:'这个代码可以改进吗?怎么样?'
  • @FelixKling 谢谢。我不知道代码审查。我试试看!
  • 我投票结束这个问题,因为它属于 codereview.stackexchange.com。

标签: javascript arrays node.js object


【解决方案1】:

我会尽量避免修改 forEach 回调中的变量,这些变量是在它之外定义的。

这是一个带有reduce 的版本,它将所有状态存储在reduce 累加器中。最后,您可以提取包含结果对象的部分。它假定日期按升序排列,您可以在查询中处理:

result = result.reduce( (acc, {tvshow, airdate}) => {
    acc.i += acc.airdate !== airdate;
    acc.airdate = airdate;
    acc.obj[`day${acc.i}`] = (acc.obj[`day${acc.i}`] || []).concat(tvshow);
    return acc;
}, {i:0, obj: {}} ).obj;

let result = [ 
   {
    tvshow: 'house',
    airdate: '2017-02-01T00:00:00.000Z'
   },
   {
    tvshow: 'big bang theory',
    airdate: '2017-02-01T00:00:00.000Z' 
   },
   {
    tvshow: 'simpsons',
    airdate: '2017-02-02T00:00:00.000Z'
   },
   {
    tvshow: 'suits',
    airdate: '2017-02-02T00:00:00.000Z' 
   },
   {
    tvshow: 'sun',
    airdate: '2017-02-03T00:00:00.000Z' 
   },
   {
    tvshow: 'blacklist',
    airdate: '2017-02-03T00:00:00.000Z'
  },
  {
    tvshow: 'something',
    airdate: '2017-02-03T00:00:00.000Z' 
  },
  {
    tvshow: 'homeland',
    airdate: '2017-02-03T00:00:00.000Z' 
  },
  {
    tvshow: 'american dad',
    airdate: '2017-02-04T00:00:00.000Z'
  },
  {
    tvshow: 'games',
    airdate: '2017-02-05T00:00:00.000Z' 
  }
];

result = result.reduce( (acc, {tvshow, airdate}) => {
    acc.i += acc.airdate !== airdate;
    acc.airdate = airdate;
    acc.obj[`day${acc.i}`] = (acc.obj[`day${acc.i}`] || []).concat(tvshow);
    return acc;
}, {i:0, obj: {}} ).obj;

console.log(result);

我用moment 省略了格式,这不是此代码中的决定因素。你可以添加它。

【讨论】:

  • 谢谢!它看起来好多了。我得看看reduce函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 2020-06-30
相关资源
最近更新 更多