0

I'm stuck again with some flattening and renaming of the following. What I got:

  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
    }
  ]

What I try to achieve:

  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
    }
  ]

I'm quite aware that my approach isn't the right thing. I tried different things so far but couldn't get it working. I'm totally stuck again to find the right way because I do run into two main issues:

How can I make the difference between first and last values? (switch case or if and if else?) and How can I access the name property from the station object and assign it to the key of "station"

Here is my last approach which is still missing the right code for the mentioned problems:

  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;
      }
    });
  }
1
  • What is your input for the convertTest function? A proper input could help better understand what you're trying to do Commented Jul 18, 2020 at 8:37

4 Answers 4

1

You could take a recursive approach for all other nested objects except the first level with special cases.

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; }

Sign up to request clarification or add additional context in comments.

Comments

0

You should use Map and 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]
      });
    });
  }
  
  
  
  
  

1 Comment

This solution helped me most to get a new idea of how to solve my problem - although Nina's Solution works, too. Thank's to all other ones, too!
0

Please try this.

 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;
  })

Comments

0

You can use Array.prototype.reduce to flatten as per your requirement

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.