【问题标题】:Create new object based on two other objects基于其他两个对象创建新对象
【发布时间】:2018-08-03 13:20:52
【问题描述】:

我的 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)

这为我提供了一个基于支出.byDays 的过滤和排序数组。但是,我不知道如何进行。在过去的几个小时里,我用reduce 尝试了一些东西,但我无法修复它。

感谢您的帮助!

【问题讨论】:

    标签: reactjs ecmascript-6 redux react-redux


    【解决方案1】:

    我能想到的解决方案。参考下面的回复

    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

    【讨论】:

    • 像魅力一样工作!谢谢。
    【解决方案2】:

    你的想法是对的。但是,从 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
        }
      ]
    }
    

    【讨论】:

    • 对。但是在结果中,我需要将支出按天分组,以天为键。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多