JavaScript: change array objects into a string separated by dots

Task: Converting Nested Objects in an Array to Dot Notation String Using JavaScript

Here is a sample data structure that needs to be converted:

[
  {
    property: 'name',
    children: [],
    message: 'name should not be empty',
  },
  {
    property: 'priceForm',
    children: [
      {
        property: 'priceCurrency',
        children: [],
        message: 'priceCurrency should not be empty',
      },
    ],
  },
  {
    property: 'priceForm',
    children: [
      {
        property: 'rolePrices',
        children: [
          {
            property: '0',
            children: [
              {
                property: 'markupType',
                children: [],
                message: 'markupType should not be empty',
              },
            ],
          },
        ],
      },
    ],
  },
]

Desired Output:

{
  'name': 'name should not be empty',
  'priceForm.priceCurrency': 'priceCurrency should not be empty',
  'priceForm.rolePrices.0.markupType': 'markupType should not be empty',
}

Answer №1

To start, the collection of the path is recommended before constructing a property.

function getObject(array, path = '', target = {}) {
    array.forEach(({ property, children = [], message }) => {
        var temp = path + (path && '.') + property;
        if (children.length) {
            getObject(children, temp, target);
            return;
        }
        target[temp] = message;
    });
    return target;   
}

var array = [{ property: 'name', children: [], message: 'name should not be empty' }, { property: 'priceForm', children: [{ property: 'priceCurrency', children: [], message: 'priceCurrency should not be empty' }] }, { property: 'priceForm', children: [{ property: 'rolePrices', children: [{ property: '0', children: [{ property: 'markupType', children: [], message: 'markupType should not be empty' }] }] }] }],
    object = getObject(array);
    
console.log(object);

Answer №2

One interesting approach is to utilize a recursive function for custom formatting.

const data = [{ property: 'name', children: [], message: 'name should not be empty' }, { property: 'priceForm', children: [{ property: 'priceCurrency', children: [], message: 'priceCurrency should not be empty' }] }, { property: 'priceForm', children: [{ property: 'rolePrices', children: [{ property: '0', children: [{ property: 'markupType', children: [], message: 'markupType should not be empty' }] }] }] }];

let result = {};
function formatData(data, prefix) {
    prefix = prefix ? `${prefix}.` : '';
    let message = '';
    data.forEach(item => {
        prefix = `${prefix}${item.property}`;
        message = item.message;
        if (!item.children.length) {
            item.message && (result[prefix] = item.message);
        } else {
            let childData = formatData(item.children, prefix);
            childData['message'] && childData['prefix'] && (result[`${prefix}.${childData['prefix']}`] = childData['message']);
        }
        prefix = '';
    });

    return { prefix: prefix, message: message };
}

formatData(data);

console.log(result);

Answer №3

Here is the solution using Array.reduce and recursion to solve this problem.

const foo = (data, prefix = "") =>
  data.reduce(
    (acc, { property, message, children }) => ({
      ...acc,
      ...(children.length
        ? foo(children, `${prefix}${property}.`)
        : { [`${prefix}${property}`]: message })
    }),
    {}
  );

const data = [
  {
    property: "name",
    children: [],
    message: "name should not be empty"
  },
  {
    property: "priceForm",
    children: [
      {
        property: "priceCurrency",
        children: [],
        message: "priceCurrency should not be empty"
      }
    ]
  },
  {
    property: "priceForm",
    children: [
      {
        property: "rolePrices",
        children: [
          {
            property: "0",
            children: [
              {
                property: "markupType",
                children: [],
                message: "markupType should not be empty"
              },
              {
                property: "sibling!",
                children: [],
                message: "added a sibling to the input data"
              }
            ]
          }
        ]
      }
    ]
  }
];


console.log(foo(data));

Update simplified the code. It's now basically a one-liner 🙌 Also added a sibling to the input data

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

Is it necessary to call detach() in rangy?

Utilizing the rangy library in my project and reviewing the documentation for detach: "Destroys the range when it is no longer to be used." I am encountering a dilemma as there isn't a suitable location for me to invoke detach in my code for certain ...

Having trouble with Ajax and facebox integration issues?

My website utilizes ajax jquery and facebox for interactive features. You can check out a demo here. The div with the ID "#content" contains links to other pages that open successfully using facebox. However, when I reload the content of this div using aj ...

The $.get method in AJAX/jQuery is functioning properly, however, there seems to be an issue with

Yesterday, I successfully made my first AJAX call by using this function that was connected to a button click event. function ajaxFunction(){ $.get("ajax/calendar.php", function(data){ $('#ajaxResponse').html(data); }); }; Now, I want t ...

Guide to developing a custom plugin for Nuxt.js

This is the content of my rpc.js plugin file: const { createBitcoinRpc } = require('@carnesen/bitcoin-rpc') const protocol = 'http' const rpcuser = 'root' const rpcpassword = 'toor' const host = '127.0.0.1&apo ...

jQuery's Ajax feature fails to transmit information

I am facing an issue with my asp.net core backend project where my method is not receiving the data sent by jQuery ajax https://i.sstatic.net/O9wYg.png Here are the scripts I am using to send data: function ChangeCount(productId, count) { $.ajax({ ...

Can anyone tell me where to locate the AndroidManifest.xml file within a React Native Expo project?

How can I locate the AndroidManifest.xml file in a React Native Expo project to request permissions? Are there alternative methods for asking users for permission? ...

How can I specify which specific div I want to run code on, rather than all divs with the

This code is affecting all instances of .flow-hold instead of just the div below the .title-hold with text that matches the ==. The reason for this is because I need to adjust the ranges used for each gauge1, gauge2, and gauge3 instances. I attempted $(&ap ...

Failure to fetch data through Axios Post method with a Parameter Object

I've encountered an issue with Axios while attempting to make a post request with a parameters object to a Laravel route. If I use query parameters like ?username=user, the post request works successfully. However, when I use an object, it fails: Be ...

Obtain the ClientID for a particular user control that is within a repeater's bindings

I have a collection of user controls that I am connecting to a repeater. The user control: (Example) "AppProduct" <div> <asp:Button ID="btn_details" runat="server" Text="Trigger" /> <asp:HiddenField ID="pid" ...

Is there a way to determine the app bar height within a React Material UI application?

I'm trying to create a full-screen image for the opening of my website using React and Material UI. Here's a snippet of my JSX code with the default Material UI theme: <AppBar> //code in between </AppBar> <Container sx={{margin: ...

How to Develop a WebSocket Client for Mocha Testing in a Sails.js Application?

I've been attempting to utilize the socket.io-client within the Mocha tests of my Sails JS application for making calls like the one shown below. However, the .get/.post methods are not being invoked and causing the test case to time out. var io = re ...

JavaScript Variables Lose Their Values

Similar Inquiry: How can I get the response from an AJAX call in a function? I have written a function that fetches numerical data from an online file. Although the file retrieval is successful (verified by the alert message), I encounter an issue whe ...

Why styled-components namespace problem in React Rollup build?

I designed a "UI Library" to be utilized in various projects using ReactJS + TypeScript + styled-components and Rollup. However, I am currently encountering issues with conflicting classNames. I am aware that styled-components offers a plugin for creating ...

Eliminate redundant tags using jQuery

I have a code snippet that I need help with. I want to check for duplicates and if found, display an alert stating that it already exists so users can't insert the same word/tag again. Can someone please assist me? <div id="tags"> <span>a ...

Creating a counter while iterating over a JSON array in jq

I am currently working with jq-1.5. My goal is to generate a running counter (index) for a JSON array. The JSON data I have is: {"Actors": "Tom,Dick,Mary"} To split the string into an array, I am using splits(): echo '{"Actors": "Tom,Dick,Mary"}&a ...

Utilizing an Async API call from a separate page and passing it as a component input

I recently set up an asynchronous API fetch in one of my .JS files and then invoked it from another JS file to output the result using console.log. (Is there a more efficient method for achieving this?) Now, my aim is to utilize the fields of the response ...

Save a canvas image directly to your WordPress media library or server

I'm working on integrating a feature that enables users to save a png created on a canvas element into the WordPress media library, or at least onto the server (which is an initial step before sharing the image on Facebook, as it requires a valid imag ...

Combining Arrays with Matching Index in Objective-C

Can anyone help me with merging two arrays with the same index in JSON format? Here is an example of my JSON data: "tier_info": [ { "tier_id": "1", "tier_name": "tier-1", "price": "3.9", "ios_id": "tier-1", "and ...

Three.js: Create a Custom Cube Panorama with Adjustable Orientation (Front, Back, Left, Right, etc.)

For my project, I am implementing a rotating cube panorama image with 6 sides: Check out the example here View the code on GitHub scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 100 ); cam ...

Pattern for identifying JavaScript import declarations

My task involves using node to read the contents of a file. Specifically, I am looking to identify and extract a particular import statement within the file that includes the "foo-bar" package. The goal is to match only the line or lines that contain the ...