1

Suppose I have two arrays like these:

const dataset = [{n: "2", s: 'hello', b: 'TRUE'}, {n: "0", s: 'meow', b: 'FALSE'}]
const info = {n:{type: 'TEXT'}, s:{type: 'PARAGRAPH'}, b:{type: 'CHECKBOX'}}

and I want to transform dataset in this:

const dataset = [{n: 2, s: 'hello', b: true}, {n: 0, s: 'meow', b: false}]

so values with key n become numbers, values with key s became stringa and values with key b became booleans.

So I created this function to match info type and the key:

function dataType(formType) {
  switch (formType) {
    case 'TEXT':
      return 'number'
    case 'PARAGRAPH':
      return 'string'
    case 'CHECKBOX':
      return 'boolean'
    default:
      throw new Error(`Something went wrong.`)
  }
}

Now I need a function that parse dataset, check each object and transform all the values. I prefer to make a copy of dataset, so immutability.

I think to use a reduce but I need help:

function dataParse(dataset, info) {
  const result = dataset.map((datum) => {
    return Object.entries(datum).reduce((acc, curr, i) => {
      // ???
      return acc
    }, {})
  })
  return result
}

I suppose to use a code similar to:

let v // don't like let
switch (value) {
          case 'number':
            v = +response
            break
          case 'string':
            v = response.toString()
            break
          case 'boolean':
            v = v === 'TRUE' ? true : false
            break
          default:
            throw new Error(`Something went wrong.`)

but how?


The complete code is here:

function dataType(formType) {
  switch (formType) {
    case 'TEXT':
      return 'number'
    case 'PARAGRAPH':
      return 'string'
    case 'CHECKBOX':
      return 'boolean'
    default:
      throw new Error(`Something went wrong.`)
  }
}

function dataParse(dataset, info) {
  const result = dataset.map((datum) => {
    return Object.entries(datum).reduce((acc, curr, i) => {
      // ???
      return acc
    }, {})
  })
  return result
}

const dataset = [{n: "2", s: 'hello', b: 'TRUE'}, {n: "0", s: 'meow', b: 'FALSE'}]
const info = {n:{type: 'TEXT'}, s:{type: 'PARAGRAPH'}, b:{type: 'CHECKBOX'}}

console.log(dataParse(dataset, info))

2 Answers 2

1

I would just do a loop, and drop the info object like so

const dataset = [{n: "2", s: 'hello', b: 'TRUE'}, {n: "0", s: 'meow', b: 'FALSE'}]

const newDataset = dataset.map((data) => {
  return {n: parseInt(data.n), s: data.s, b: data.b === "TRUE" ? true : false}
})

console.log(newDataset)
or something similar. If you are sure that n always contains a number and b is always either "TRUE"or "FALSE", I think this is the way to go.

Otherwise, to continue on your example:

function transform(data, info) {
  let newObj = {};
  Object.keys(data).forEach((key) => {
    switch(info[key].type) {
      case 'TEXT':
        newObj[key] = parseInt(data[key])
        break;
      case 'PARAGRAPH':
        newObj[key] = data[key]
        break;
      case 'CHECKBOX':
        newObj[key] = data[key] === "TRUE" ? true : false;
        break;
      default:
        throw new Error(`Something went wrong.`)
    }
  })
  return newObj
}

function dataParse(dataset, info) {
  const result = dataset.map((datum) => {
    return transform(datum, info)
  })
  return result
}

const dataset = [{n: "2", s: 'hello', b: 'TRUE'}, {n: "0", s: 'meow', b: 'FALSE'}]
const info = {n:{type: 'TEXT'}, s:{type: 'PARAGRAPH'}, b:{type: 'CHECKBOX'}}

console.log(dataParse(dataset, info))

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

1 Comment

Thank you, but it's not so simple. I have to use info object and dataType function
1

Your attempt is almost right.

It's also possible with Array#reduce(), but there's a relatively new method, Object.fromEntries(), that reverses Object.entries(), and makes your life easier:

function convert(value, formType) {
  switch (formType) {
    case 'TEXT':
      return Number(value) //Same as `+value`
    case 'PARAGRAPH':
      return String(value) //Better than `toString()`, works with all values
    case 'CHECKBOX':
      return value === 'TRUE' //No need for ternary here, `===` already returns a boolean!
    default:
      throw new Error(`Something went wrong.`)
  }
}

function dataParse(dataset, info){
  return dataset.map(obj => 
    Object.fromEntries(
      Object.entries(obj).map(([k, v]) => 
        [k, convert(v, info[k].type)]
      )
    )
  )
}

const dataset = [{n: "2", s: 'hello', b: 'TRUE'}, {n: "0", s: 'meow', b: 'FALSE'}]
const info = {n:{type: 'TEXT'}, s:{type: 'PARAGRAPH'}, b:{type: 'CHECKBOX'}}

console.log(dataParse(dataset, info))

If you have to use the dataType for handling types, you can change convert to accept the type returned by dataType instead:

function convert(value, formType) {
  switch (formType) {
    case 'number':
      return Number(value) //Same as `+value`
    case 'string':
      return String(value) //Better than `toString()`, works with all values
    case 'boolean':
      return value === 'TRUE' //No need for ternary here, `===` already returns a boolean!
    default:
      throw new Error(`Something went wrong.`)
  }
}

function dataType(formType) {
  switch (formType) {
    case 'TEXT':
      return 'number'
    case 'PARAGRAPH':
      return 'string'
    case 'CHECKBOX':
      return 'boolean'
    default:
      throw new Error(`Something went wrong.`)
  }
}

function dataParse(dataset, info){
  return dataset.map(obj => 
    Object.fromEntries(
      Object.entries(obj).map(([k, v]) => 
        [
          k, 
          convert(
            v, 
            dataType(info[k].type)
          )
        ]
      )
    )
  )
}

const dataset = [{n: "2", s: 'hello', b: 'TRUE'}, {n: "0", s: 'meow', b: 'FALSE'}]
const info = {n:{type: 'TEXT'}, s:{type: 'PARAGRAPH'}, b:{type: 'CHECKBOX'}}

console.log(dataParse(dataset, info))

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.