【问题标题】:Javascript flatten deeply nested Array with objects and renaming propertiesJavascript 使用对象和重命名属性来扁平化深度嵌套的数组
【发布时间】:2020-11-07 23:49:42
【问题描述】:

我再次陷入对以下内容的一些扁平化和重命名中。 我得到了什么:

  test = [
    {
      date: '2020-03-30',
      station: {
        id: 0,
        name: 'some description'
      },
      firstValues: [
        {
          result: 1,
          type: 4,
          max: 18,
          min: 1,
        },
        {
          result: 2,
          type: 5,
          max: 15,
          min: 2,
        }
      ],
      lastValues: [
        {
          result: 1,
          type: 3,
          max: 17,
          min: 1
        },
        {
          result: 2,
          type: 8,
          max: 20,
          min: 2
        }
      ],
      iD: 'xxx3',
      count: 1
    },
    {
    next object with same structure
    }
  ]

我想达到的目标:

  test = [
    {
      date: '2020-03-30',
      station: 'some description',
      first_E01_result: 1,
      first_E01_type: 4,
      first_E01_max: 18,
      first_E01_min: 1,
      first_E02_result: 2,
      first_E02_type: 5,
      first_E02_max: 15,
      first_E02_min: 2,
      last_E01_result: 1,
      last_E01_type: 3,
      last_E01_max: 17,
      last_E01_min: 1,
      last_E02_result: 2,
      last_E02_type: 8,
      last_E02_max: 20,
      last_E02_min: 2,
      iD: 'xxx3',
      count: 1
    },
    {
    next object with same structure
    }
  ]

我很清楚我的方法是不正确的。到目前为止,我尝试了不同的方法,但无法正常工作。我又完全陷入了寻找正确方法的困境,因为我确实遇到了两个主要问题:

如何区分第一个值和最后一个值? (切换大小写或 if 和 if else?) 和 如何从站对象访问名称属性并将其分配给“站”的键

这是我的最后一种方法,但仍然缺少解决上述问题的正确代码:

  convertTest(input) {
    return input.map(obj => {
      const obj1 = {};
      const obj2 = {};
      for (const prop in obj) {
        if (obj.hasOwnProperty(prop) && Array.isArray(obj[prop])) {
          for (let i = 0; i < obj[prop].length; i++) {
            for (const [key, value] of Object.entries(obj[prop][i])) {
              const name = 'first_EO' + (i + 1).toString() + '_' + key;
              obj2[name] = value;
            }
          }
        } else {
          obj1[prop] = obj[prop];
        }
        const dataconverted = Object.assign({}, obj1, obj2);
        return dataconverted;
      }
    });
  }

【问题讨论】:

  • 您对convertTest 函数的输入是什么?正确的输入可以帮助您更好地了解您要做什么

标签: javascript arrays rename flatten


【解决方案1】:

请试试这个。

 test = test.map((elem) => {
    elem.firstValues.forEach((child, index) => {
      for(let key in child){
        let v =  `first_E${index+1}_${key}`
        elem[v] = child[key];
      }
    })
    elem.lastValues.forEach((child, index) => {
      for(let key in child){
        let v =  `last_E${index+1}_${key}`
        elem[v] = child[key];
      }
    })
    elem['station'] = elem.station.name;
    delete elem.firstValues;
    delete elem.lastValues;
    return elem;
  })

【讨论】:

    【解决方案2】:

    你应该使用 Map 和 Object.keys

    var test = [{"date":"2020-03-30","station":{"id":0,"name":"some description"},"firstValues":[{"result":1,"type":4,"max":18,"min":1},{"result":2,"type":5,"max":15,"min":2}],"lastValues":[{"result":1,"type":3,"max":17,"min":1},{"result":2,"type":8,"max":20,"min":2}],"iD":"xxx3","count":1}]
      
      console.log(flatten(test));
      
      function flatten(arr) {
        return arr.map(el => ModifyObject(el))
      }
      
      function ModifyObject(el) {
        const obj = {};
        obj.date = el.date;
        obj.iD = el.iD;
        obj.count = el.count;
        obj.station = el.station.name;
        flattenObjectByProperty(obj, el, 'firstValues')
        flattenObjectByProperty(obj, el, 'lastValues')
        return obj;
      }
      
      function flattenObjectByProperty(obj, el, property) {
        (el[property] || []).map((child, i) => {
          Object.keys(child).forEach(key => {
            obj[property + '_E' + i + '_' + key] = child[key]
          });
        });
      }
      
      
      
      
      

    【讨论】:

    • 这个解决方案最能帮助我了解如何解决我的问题 - 尽管 Nina 的解决方案也有效。也感谢所有其他人!
    【解决方案3】:

    您可以对所有其他嵌套对象采用递归方法,但具有特殊情况的第一级除外。

    var data = [{ date: '2020-03-30', station: { id: 0, name: 'some description' }, firstValues: [{ result: 1, type: 4, max: 18, min: 1 }, { result: 2, type: 5, max: 15, min: 2 }], lastValues: [{ result: 1, type: 3, max: 17, min: 1 }, { result: 2, type: 8, max: 20, min: 2 }], iD: 'xxx3', count: 1 }],
        getPath = object => Object.entries(object).reduce((r, [k, v], i) => {
            if (v && typeof v === 'object') {
                r.push(...getPath(v).map(([left, right]) => [(Array.isArray(object) ? 'E' + (i + 1).toString().padStart(2, 0) : k) + '_' + left, right]));
            } else {
                r.push([k, v]);
            }
            return r;
        }, []),
        result = data.map(o => Object.fromEntries(Object.entries(o).reduce((r, [k, v]) => {
            if (k === 'station') {
                r.push([k, v.name]);
            } else if (v && typeof v === 'object') {
                if (k.endsWith('Values')) k = k.slice(0, -6);
                r.push(...getPath(v).map(([left, right]) => [k + '_' + left, right]));
            } else {
                r.push([k, v]);
            }
            return r
        }, [])));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案4】:

      您可以根据需要使用Array.prototype.reduce 进行展平

      const test = [
          {
            date: '2020-03-30',
            station: {
              id: 0,
              name: 'some description'
            },
            firstValues: [
              {
                result: 1,
                type: 4,
                max: 18,
                min: 1,
              },
              {
                result: 2,
                type: 5,
                max: 15,
                min: 2,
              }
            ],
            lastValues: [
              {
                result: 1,
                type: 3,
                max: 17,
                min: 1
              },
              {
                result: 2,
                type: 8,
                max: 20,
                min: 2
              }
            ],
            iD: 'xxx3',
            count: 1
          }
      ];
      
      const result = test.reduce((acc, curr) => {
          const { firstValues, lastValues, ...rest } = curr;
          
          const modifiedFirstValues = firstValues.reduce((r, c, i) => {
              Object.entries(c).forEach(([key, value]) => {
                  const modifiedKey = `first_E${i + 1}_${key}`;
                  r[modifiedKey] = value;
              });
              return r;
          }, Object.create(null));
          
          const modifiedLastValues = lastValues.reduce((r, c, i) => {
              Object.entries(c).forEach(([key, value]) => {
                  const modifiedKey = `last_E${i + 1}_${key}`;
                  r[modifiedKey] = value;
              });
              return r;
          }, Object.create(null));
          
          const finalObj = {
              ...rest,
              ...modifiedFirstValues,
              ...modifiedLastValues
          };
          acc.push(finalObj);
          return acc;
      }, []);
      
      console.log(result);

      【讨论】:

        猜你喜欢
        • 2023-04-08
        • 2014-08-12
        • 2020-09-23
        • 2020-07-12
        • 2016-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多