Update the values of an array of objects using their respective keys

Let's say we have two arrays defined as:

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 the goal is to convert dataset into the following format:

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

where values with key n are transformed into numbers, those with key s into strings, and with key b into booleans.

A function was created to match the type in info with the corresponding 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 a function is needed to check each object in dataset, transform all the values according to the matching types in info, while making a copy of the dataset for immutability purposes.

The idea is to use a reduce method but some guidance is required:

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

An example of how to handle values could be like this:

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 would that work exactly?


The complete code snippet is provided below:

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

Answer №1

If I were to approach this, I would use a loop and extract the information object in the following manner:

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 a similar approach. If you are confident that n always holds a number and b is consistently either "TRUE" or "FALSE", then this method should suffice.

Alternatively, building upon 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))

Answer №2

Almost there with your solution attempt.

Consider utilizing Object.fromEntries(), a newer method that simplifies the process by reversing Object.entries():

function convertData(value, dataType) {
  switch (dataType) {
    case 'TEXT':
      return Number(value);
    case 'PARAGRAPH':
      return String(value);
    case 'CHECKBOX':
      return value === 'TRUE';
    default:
      throw new Error(`Something went wrong.`);
  }
}

function processData(dataArr, dataInfo){
  return dataArr.map(obj => 
    Object.fromEntries(
      Object.entries(obj).map(([k, v]) => 
        [k, convertData(v, dataInfo[k].type)]
      )
    )
  )
}

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

console.log(processData(dataArr, dataInfo))

To enhance the code further, consider modifying the convertData function to receive the type returned by dataInfo:

function convertData(value, dataType) {
  switch (dataType) {
    case 'number':
      return Number(value);
    case 'string':
      return String(value);
    case 'boolean':
      return value === 'TRUE';
    default:
      throw new Error(`Something went wrong.`);
  }

}

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

function processData(dataArr, dataInfo){
  return dataArr.map(obj => 
    Object.fromEntries(
      Object.entries(obj).map(([k, v]) => 
        [
          k, 
          convertData(
            v, 
            determineDataType(dataInfo[k].type)
          )
        ]
      )
    )
  )
}

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

console.log(processData(dataArr, dataInfo))

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guidelines for capturing a div screenshot with javascript

Let's say I have a div containing an image source. <div> <p class="row">With custom CSS</p> <img src="/images/midhun.jpg"> </div> When a button is clicked, I want to display a screenshot of this image in another div. C ...

PHP: Eliminating Line Breaks and Carriage Returns

My content entered into the database by CKEditor is adding new lines, which poses a problem as I need this data to be rendered in JavaScript as a single line of HTML. Within my PHP code, I have implemented the following steps: $tmpmaptext = $map['ma ...

Eternal loop trapping node.js function

Here's the scenario: var getTexts = new cronJob('* 5 * * * *', function() { let weekday = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY&apos ...

Understanding the sequence of operations in Javascript using setTimeout()

If I have the following code: function testA { setTimeout('testB()', 1000); doLong(); } function testB { doSomething(); } function doLong() { //takes a few seconds to do something } When I run testA(), what happens after 1000 mill ...

The initial request does not include the cookie

My server.js file in the express application has the following code: var express = require('express'); var fallback = require('express-history-api-fallback'); var compress = require('compression'); var favicon = require(&apos ...

"Unleashing the power of Ionic: Why ng-click fires twice in Mobilefirst

Operating Environment: Eclipse 4.4.2, IBM MobileFirst Platform Foundation 7.1, StarterApplication_ionic-release71.zip, angular-route.js [AngularJS v1.2.12 part of sample application] and ionic.bundle.js [Ionic, v1.0.0-beta.1 part of sample application] ...

Unable to access the camera page following the installation of the camera plugin

The issue I'm encountering involves using the native camera with the capacitor camera plugin. After implementation, I am unable to open the page anymore - clicking the button that should route me to that page does nothing. I suspect the error lies wit ...

Select the even-numbered occurrences of a specific class in CSS using the nth-child()

I am encountering an issue with my table layout. The structure is similar to the following: <tbody> <tr class="row">...</tr> <tr class="row--expanded">...</tr> <tr class="row">...</ ...

Adjust the iframe height when using slidetoggle

I currently have a menu positioned in the center of the screen, set to "show" by default. Beneath this menu, there is an iframe filling up the remaining space: <script type="text/javascript> $(document).ready(function() { var main_height = ($(d ...

Accessing data from arrays asynchronously using JavaScript

Update I have included actual code below, in addition to the concept provided earlier. Here is the async array access structure I am trying to implement: for (p = 0; p < myList.length ; p++){ for (k = 0; k < RequestList.length; k++){ i ...

Download a portion of the webpage as an HTML file

I need help figuring out how to save a specific portion of a webpage as an HTML file. Currently, I manually go through the process by using F12 developer tools in Chrome or Mozilla to locate and select the desired content. Once I find the div element with ...

Is there a way to customize the outlined color of an input adornment in MUI?

Looking to customize the default blue color in a Form Control outlined variant, but can't figure out how. I was able to do it with a regular TextField, but this one is a bit trickier. <FormControl variant="outlined"> < ...

Unable to establish connection with server through Ajax request on HTML page

I set up a NodeJs server using the Express module. However, I am facing issues with implementing an AJAX request from an HTML page using $.ajax when clicking a button. I want to retrieve data from the server in either JSON or text format but for some reaso ...

The parent component is ignoring the emitted event from the child

I recently built a form component called Form.vue that is nested within PostPage.vue. In the 'Form.vue' component, I am trying to trigger a $emit event to notify the parent component and update a Prop value called btn-text. Parent Component Post ...

Achieving unique proportions with HTML5 video resizing

On my page, I plan to showcase a video specifically for desktop browsers. I have devised some code to determine whether the video is in landscape or portrait orientation. The challenge lies in deciding what to do based on this orientation: If the video is ...

the click event fails to trigger when the id or class is modified

Hey there, I'm new to working with jquery and I've encountered a problem. Here's the code snippet: http://jsfiddle.net/8guzD/ $('#test.off').click(function(){ $(this).removeClass('off').addClass('on'); }) ...

I discovered an issue in Handsontable while trying to copy and paste a numeric value in German format

For my upcoming project, I am looking to incorporate the Handsontable JavaScript grid framework. However, I have encountered a small bug that is hindering me from utilizing this library to its fullest potential. The task at hand involves displaying a tabl ...

The retrieval of JSON data is successful in Internet Explorer, but it encounters issues in Firefox and

My MVC app is experiencing JSON request failures in Firefox but works fine on IE and Chrome. I initially suspected the same-origin policy, but all requests are using the same host and protocol (localhost). Upon inspecting the network functions of each brow ...

Calculating the sum of table columns with the help of knockout.js

Is there a way to calculate the table columns using knockout.js? I am familiar with jQuery but new to knockout.js and unsure how to approach this. Instead of generating the table data using JSON, I would like to directly create it in the HTML table itself. ...

Experiencing a 403 Error while using request-promise to extract price data from a website

My current challenge involves using request-promise to scrape the price of an item from Asos.com. Whenever I try to execute the code provided below, I encounter a 403 error. Could it be possible for this error to occur even though the URL I am attempting t ...