簡體   English   中英

使用lodash或ramda變換對象數組

[英]Transform array of objects using lodash or ramda

這是查詢數據庫后獲得的數據結構。

[
    { name: 'xx1', date: '2017-09-03', value: 49 },
    { name: 'xx2', date: '2017-10-23', value: 67 },
    { name: 'xx2', date: '2017-12-01', value: 70 },
    ...
]

我想將其轉換為:

[
    { name: 'xx1', data: { '2017-09-03': 49 } },
    { name: 'xx2', data: { '2017-10-23': 67, '2017-12-01': 70 } },
    ...
]

為了使用react-chartkick構建圖表,需要該數據結構。

誰能給我建議解決這個問題? (尤其是lodash或ramda)

我將基於reducefind (ES6)方法使用以下方法:

const data = [
  { name: 'xx1', date: '2017-09-03', value: 49 },
  { name: 'xx2', date: '2017-10-23', value: 67 },
  { name: 'xx2', date: '2017-12-01', value: 70 }
];

const result = data.reduce((acc, item) => {
  const found = acc.find(a => a.name === item.name);
  if (found) {
     found.data[item.date] = item.value;
  } else {
    acc.push({
      name: item.name,
      data: {
        [item.date]: item.value
      }
    });
  }
  return acc;
}, []);

如果您不希望使用ES6,則這兩種方法都具有lodash版本: reducefind

您可以使用Array#reduce()累積對象並返回其Object.values()

 const data = [ { name: 'xx1', date: '2017-09-03', value: 49 }, { name: 'xx2', date: '2017-10-23', value: 67 }, { name: 'xx2', date: '2017-12-01', value: 70 } ] const map = data.reduce((acc, { name, date, value }) => { if (!(name in acc)) { acc[name] = { name, data: {} } } acc[name].data[date] = value return acc }, {}) const result = Object.values(map) console.log(result) 

這種方法避免使用Array#find() ,它的時間復雜度為O(n),並且name in acc使用name in acc來檢查是否存在,並且使用acc[name]進行訪問,這兩者都是O(1)的時間復雜度,因此該方法為O(n ) 總體。

相反, 另一個答案是總體的O(n 2 )時間復雜度。

對於使用lodash的解決方案,可以使用其_.map_.groupBy_.merge方法來完成此任務。

我發現使用_.chain樣式更容易_.chain ,但是您可以根據需要輕松地將其轉換為一組普通的嵌套調用。

 const data = [ { name: 'xx1', date: '2017-09-03', value: 49 }, { name: 'xx2', date: '2017-10-23', value: 67 }, { name: 'xx2', date: '2017-12-01', value: 70 }, ] const result = _.chain(data) .map(val => ({name: val.name, data: {[val.date]: val.value}})) // convert objects to desired format .groupBy("name") // group objects by name .map(v => _.merge(...v)) // merge objects in each group .value(); // done! console.log(result); 
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script> 

R.reduceByR.reduceByR.groupBy可以在這里為您提供幫助。 在下面的示例中, R.reduceBy通過name屬性對數組中的對象進行分組,然后通過使用R.assoc建立新對象來組合分組的元素。 R.toPairsR.mapR.zipObj的其余組合將結果轉換為所需的形狀。

 const fn = R.pipe( R.reduceBy((res, {date, value}) => R.assoc(date, value, res), {}, R.prop('name')), R.toPairs, R.map(R.zipObj(['name', 'data'])) ) const data = [ { name: 'xx1', date: '2017-09-03', value: 49 }, { name: 'xx2', date: '2017-10-23', value: 67 }, { name: 'xx2', date: '2017-12-01', value: 70 } ] console.log(fn(data)) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM