【问题标题】:Rebuilding/Parsing plain JavaScript object重建/解析纯 JavaScript 对象
【发布时间】:2021-04-16 03:55:31
【问题描述】:

假设我每个人都有一个 object containing objects that have 30 key-value pairs

const data = {
        "foo": {
            "3/16/21": 'buzz',
            "3/17/21": 'fizz',
            ...
            "4/13/21": 'lorem',
            "4/14/21": 'ipsum'
        },
        "bar": {
            "3/16/21": 'sit',
            "3/17/21": 'amet',
            ...
            "4/13/21": 'dummy',
            "4/14/21": 'text'
        },
    };

我的目标是将这个对象重建成这样的:

myData = [
        {date: "3/16/21", foo: 'buzz', bar : 'sit'}
        {date: "3/17/21", foo: 'fizz', bar : 'amet'} ,
            ...
        {date: "4/13/21", foo: 'lorem', bar : 'dummy'}
        {date: "4/14/21", foo: 'ipsum', bar : 'text'}
         ];

下面的功能就像魅力一样,但我觉得有一个 10 倍更好的方法来做到这一点。我很想看看你对我如何改进它的建议。

const processAPIdata = (data) => {
        if (data) {
            var myData = [];

            for (var key in data) {
                if (!data.hasOwnProperty(key)) continue;
                var obj = data[key];
                for (var prop in obj) {

                    if (!obj.hasOwnProperty(prop)) continue;
                    if (myData.length < 30) {
                        myData.push({ date: prop });
                    }
                    let pos = myData.map(function (e) { return e.date; }).indexOf(prop);
                    myData[pos][key] = obj[prop];
                }
            }
        }
        return myData;
    };

【问题讨论】:

    标签: javascript arrays object parsing


    【解决方案1】:

    我会组合成一个按日期索引的对象。迭代时,如果该日期尚不存在,则创建该日期的对象,使用{ date }(其中date 是被迭代的内部属性),并从外部键分配一个新属性(用于新键)和内部值(对于新值):

    const data = {
        "foo": {
            "3/16/21": 'buzz',
            "3/17/21": 'fizz',
            "4/13/21": 'lorem',
            "4/14/21": 'ipsum'
        },
        "bar": {
            "3/16/21": 'sit',
            "3/17/21": 'amet',
            "4/13/21": 'dummy',
            "4/14/21": 'text'
        },
    };
    
    const newDataByDate = {};
    for (const [key, obj] of Object.entries(data)) {
      for (const [date, val] of Object.entries(obj)) {
        newDataByDate[date] ??= { date };
        newDataByDate[date][key] = val;
      }
    }
    console.log(Object.values(newDataByDate));

    【讨论】:

    • 抱歉,您能解释一下 ??= 运算符在做什么吗?
    • 如果右边的表达式不存在,它会分配它。更详细:if (!newDataByDate[date]) { newDataByDate[date] = { date }; }
    • 您的解决方案似乎按预期工作。但是,如果我以后想迭代这个对象怎么办。似乎对对象数组这样做会容易得多。
    • ?我的代码(和您的预期输出)都产生了一个对象数组。我想如果你想按日期查找对象,你可以继续使用 newDataByDate 对象,但听起来你想要一个对象数组,而不是对象的对象。
    • 我正在使用您的代码获取对象的对象,稍后我将使用数组索引
    【解决方案2】:

    你可以通过这个简单的方法完成。

    const data = {"foo":{"3/16/21":'buzz',"3/17/21":'fizz',"4/13/21":'lorem',"4/14/21":'ipsum'},"bar":{"3/16/21":'sit',"3/17/21":'amet',"4/13/21":'dummy',"4/14/21":'text'},};
    
    const result = Object.entries(data).reduce((acc, [key, values]) => {
      for(const [date, v] of Object.entries(values)){
        acc[date] = acc[date] || {date}
        acc[date][[key]] = v;
      }
      
      return acc;
    }, {});
    console.log(Object.values(result));

    【讨论】:

      【解决方案3】:

      我们可以使用Object.entriesArray.reduceObject.values 来实现这一点,如下所示

      const data = {"foo":{"3/16/21":'buzz',"3/17/21":'fizz',"4/13/21":'lorem',"4/14/21":'ipsum'},"bar":{"3/16/21":'sit',"3/17/21":'amet',"4/13/21":'dummy',"4/14/21":'text'}};
      
      const formatData = (data) => {
      //Convert the object to array of arrays with value at first index being the keys and value at second index being values
        const result = Object.entries(data).reduce((acc, [key, val]) => {
        //Since we have object as value, we need to again convert to array of arrays in order to get the date and the corresponding value
          Object.entries(val).forEach(([date, innerVal]) => {
          //update the accumulator with new key-value
            acc[date] = {
              ...(acc[date] || {date}),
              [key]: innerVal
            }
          })
          return acc;
        }, {});
      
      //Return the values of the accumulator
        return Object.values(result);
      }
      
      console.log(formatData(data));
      .as-console-wrapper {
        max-height: 100% !important;
      }

      【讨论】:

        猜你喜欢
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-08
        • 1970-01-01
        • 2011-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多