基于其他两个对象创建新对象

时间:2018-08-03 13:20:53

标签: reactjs ecmascript-6 redux react-redux

我的redux存储区中有两个对象。第一个按其ID持有支出。第二个以日期为键保存所有支出id。

ID支出

expenditures: {
   byId: {
      '0e1ca91f-aad2-44c7-985a-dfd014bb67fa': {
        id: '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
        createdAt: 1480510965381,
        description: 'shoes',
        categoryId: 13,
        value: -4,
        day: 1440374400000
      },
      '65711ad0-407d-42ca-aa13-c468a56d6ee6': {
        id: '65711ad0-407d-42ca-aa13-c468a56d6ee6',
        createdAt: 1480510965470,
        description: 'groceries',
        categoryId: 12,
        value: -53.65,
        day: 1440374400000
      },
   },
}

按天计算的支出

expenditures: {
   byDays: {
      '1440374400000': [
        '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
        '65711ad0-407d-42ca-aa13-c468a56d6ee6'
      ],
      '1440720000000': [
        '02180819-3684-480a-96c4-e9fceb2557d0',
        '2201f929-7390-4b24-ba6b-b92e850fb964',
        'f492ad3a-c580-429a-8b68-a2259658d0cd',
        'f654725a-8eee-4e9a-97a8-4fd5a331473e',
        'eedc5a7d-0320-41a1-b190-79f967b42961'
      ],
   }
}

为了现在在我的组件中呈现这些内容,我需要一个基于按天支出的新对象

  1. 按特定日期过滤
  2. 降序排列
  3. 包含支出对象而不是其ID

类似这样的东西:

expenditures: {
    byDay: {
      '1440374400000': [
        {
          id: '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
          createdAt: 1480510965381,
          description: 'shoes',
          categoryId: 13,
          value: -4,
          day: 1440374400000
        },
        {
          id: '65711ad0-407d-42ca-aa13-c468a56d6ee6',
          createdAt: 1480510965470,
          updatedAt: 1480510965470,
          description: 'groceries',
          categoryId: 12,
          value: -53.65,
          day: 1440374400000
        }
      ],
   }
}

到目前为止我所拥有的:

Object.keys(state.expenditures.byDays)
      .filter((day) => day >= currentFirstDay && day <= currentLastDay)
      .sort((a, b) => b - a)

这给了我一个基于expenses.byDays的过滤和排序数组。但是,我不知道如何进行。在过去的几个小时里,我使用reduce尝试了一些方法,但无法修复。

感谢帮助!

2 个答案:

答案 0 :(得分:1)

我能想到的解决方案。请参阅下面的repl

const state = {
  expenditures: {
    byId: {
      '0e1ca91f-aad2-44c7-985a-dfd014bb67fa': {
        id: '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
        createdAt: 1480510965381,
        description: 'shoes',
        categoryId: 13,
        value: -4,
        day: 1440374400000
      },
      '65711ad0-407d-42ca-aa13-c468a56d6ee6': {
        id: '65711ad0-407d-42ca-aa13-c468a56d6ee6',
        createdAt: 1480510965470,
        description: 'groceries',
        categoryId: 12,
        value: -53.65,
        day: 1440374400000
      },
    },
    byDays: {
      '1440374400000': [
        '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
        '65711ad0-407d-42ca-aa13-c468a56d6ee6'
      ],
      '1440720000000': [
        '02180819-3684-480a-96c4-e9fceb2557d0',
        '2201f929-7390-4b24-ba6b-b92e850fb964',
        'f492ad3a-c580-429a-8b68-a2259658d0cd',
        'f654725a-8eee-4e9a-97a8-4fd5a331473e',
        'eedc5a7d-0320-41a1-b190-79f967b42961'
      ],
    }
  }
}

//Pull out relevant piece of state from redux
const byDays = state.expenditures.byDays;
const byId = state.expenditures.byId;

// convert Id to Object
const idToObjectReducer = (acc,key) => {
    if(byId[key]) {
      acc.push(byId[key]);
    }
    return acc;
};

// Sort Objects by date
const sortByDateComparator = ({createdAt : date1}, {createdAt : date2}) => date1 - date2;

// convert byDays object
const rootReducer = (acc, key) => {
  acc[key] = byDays[key].reduce(idToObjectReducer, []).sort(sortByDateComparator)
  return acc;
};


const result = Object.keys(byDays).reduce(rootReducer, {});


console.log(result);

https://repl.it/repls/ShabbyInterestingTrialsoftware

答案 1 :(得分:0)

您有正确的想法。但是,从byId结构开始很有意义,因此您从一开始就使用所有信息。由于byId对象中的支出已经具有day信息,因此您可以忽略byDay对象。

因此,从以下结构开始:

const expenditures = {
  byId: {
    '0e1ca91f-aad2-44c7-985a-dfd014bb67fa': {
      id: '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
      createdAt: 1480510965381,
      description: 'shoes',
      categoryId: 13,
      value: -4,
      day: 1440374400000
    },
    '65711ad0-407d-42ca-aa13-c468a56d6ee6': {
      id: '65711ad0-407d-42ca-aa13-c468a56d6ee6',
      createdAt: 1480510965470,
      description: 'groceries',
      categoryId: 12,
      value: -53.65,
      day: 1440374400000
    },
  }
}

我们假设第一天和最后一天的设置如下:

const currentFirstDay = 1440374400000;
const currentLastDay = 1440374400000;

然后,您可以对expenditures.byId进行过滤和排序,然后生成一个新对象:

const filtered = Object.values(expenditures.byId)
  .filter(expenditure => expenditure.day >= currentFirstDay && expenditure.day <= currentLastDay)
  .sort((a, b) => b.value - a.value);

let byDay = {}
filtered.forEach(expenditure => {
    if (!byDay[expenditure.day]) byDay[expenditure.day] = [];
    byDay[expenditure.day].push(expenditure);
})

这将导致以下结果:

{
    "1440374400000": [
    {
      categoryId: 13,
      createdAt: 1480510965381,
      day: 1440374400000
      description: 'shoes',
      id: '0e1ca91f-aad2-44c7-985a-dfd014bb67fa',
      value: -4
    },
    {
      categoryId: 12,
      createdAt: 1480510965470,
      day: 1440374400000
      description: 'groceries',
      id: '65711ad0-407d-42ca-aa13-c468a56d6ee6',
      value: -53.65
    }
  ]
}