Tips for effectively creating a fresh array of objects by extracting distinct values from arrays of child elements within a collection of parent objects

We have a requirement to extract data from objects structured like this:

[ { "first": 
    { "children" : [{ "name": "abc", "detail":"123"},
                  { "name": "def", "detail":"456"}
                 ]
    }},
  { "second": 
    { "children" : [{ "name": "ghi", "detail":"123"},
                  { "name": "jkl", "detail":"456"}
                 ]
    }},
  { "third": 
    { "children" : [{ "name": "mno", "detail":"123"},
                  { "name": "pqr", "detail":"456"}
                 ]
    }},
  { "fourth": 
    { "children" : [{ "name": "stu", "detail":"123"},
                  { "name": "vwx", "detail":"456"}
                 ]
    }},
  { "fifth": 
    { "children" : [{ "name": "yz", "detail":"123"},
                  { "name": "abc", "detail":"456"}
                 ]
    }},
  { "sixth": 
    { "children" : [{ "name": "def", "detail":"123"},
                  { "name": "ghi", "detail":"456"}
                 ]
    }}
]

Our objective is to generate a flattened array containing unique values extracted from the "name" field of each child object. The resulting array should look like this:

[{"value":"abc", "label":"abc"},
 {"value":"def", "label":"def"},
 {"value":"ghi", "label":"ghi"},
 {"value":"jkl", "label":"jkl"},
 {"value":"mno", "label":"mno"},
 {"value":"pqr", "label":"pqr"},
 {"value":"stu", "label":"stu"},
 {"value":"vwx", "label":"vwx"},
 {"value":"yz", "label":"yz"}
]

The provided code achieves the desired result, but it may not be the most efficient as it requires several passes over the array:

[
  ...new Set(
     [].concat.apply([], bases.map((base) => {
       if (!base.children || base.children.length === 0) return;
       return  base.children}
     )).map((child) => child.name)
  )
].map((optName) => {return {value: optName, label: optName};})

We are exploring alternative methods to achieve the same outcome without performing multiple iterations on the array. If you have any suggestions or optimizations, please share them.

Answer №1

Firstly, it's generally best practice not to focus on performance optimization until it becomes necessary.

Secondly, when chaining array prototype functions like map, forEach, or filter, multiple iterations are inherently part of the design.

Thirdly, there's no clear disadvantage to multiple iterations compared to a single iteration if the tasks performed in each iteration remain consistent. Tasks such as incrementing an index and comparing it with array length won't significantly impact performance when other operations involve pushing objects into arrays or checking set entries.

Here is a more streamlined code snippet for extracting unique names from an array:

let bases = [{
    children: [{
        name: "abc",
        detail: "123"
      },
      {
        name: "def",
        detail: "456"
      }
    ]
  }, {
    children: [{
        name: "abc" ,
        detail: "123"
      },
      {
        name: "xyz" ,
        detail: "456"
      }
    ]
  },
  {}
];

let output = bases
  .flatMap(b => b.children || [])
  .map(c => c.name)
  .filter((v, i, a) => a.indexOf(v) === i) // filter unique values
  .map(name => ({
    value: name,
    label: name,
  }));
  
console.log(output);

If you prefer to achieve all this in a single iteration, although less readable, it's also possible:

let bases = [{
    children: [{
        name: "abc",
        detail: "123"
      },
      {
        name: "def",
        detail: "456"
      }
    ]
  }, {
    children: [{
        name: "abc" ,
        detail: "123"
      },
      {
        name: "xyz" ,
        detail: "456"
      }
    ]
  },
  {}
];

let output = [];
let seenNames = {};
for (base of bases) {
  if (!base.children)
    continue;
  for (child of base.children) {
    let name = child.name;
    if (seenNames[name])
      continue;
    seenNames[name] = true;
    output.push({
      value: name,
      label: name,
    });
  }
}
  
console.log(output);

Answer №2

To achieve a flattened representation of data with unique values and new object mappings, consider utilizing the Array#flatMap method in JavaScript.

var data = [{ first: { children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" }] } }, { second: { children: [{ name: "ghi", detail: "123" }, { name: "jkl", detail: "456" }] } }, { third: { children: [{ name: "mno", detail: "123" }, { name: "pqr", detail: "456" }] } }, { fourth: { children: [{ name: "stu", detail: "123" }, { name: "vwx", detail: "456" }] } }, { fifth: { children: [{ name: "yz", detail: "123" }, { name: "abc", detail: "456" }] } }, { sixth: { children: [{ name: "def", detail: "123" }, { name: "ghi", detail: "456" }] } }],
    result = Array.from(
        new Set(data
            .flatMap(Object.values)
            [...]
        ),
        value => ({ value, label: value })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

(angular 8) Error occurred when converting a file or image to FormData due to an invalid value (Note: FormData object printed as Object Form{})

I encountered an issue where I am getting an invalid value from form data. The value appears correct in `this.fileData` with a size of 5701, but becomes empty when converted to form data - `{}` is logged when I console.log the form data. Additionally, acce ...

What methods can I use to identify if the browser my users are using does not have support for Bootstrap 4?

My recent project heavily utilizes the advanced features of Bootstrap 4/CSS, making it incompatible with older browsers still in use by some of my visitors. How can I effectively identify when a user's browser does not support bootstrap 4 so that I c ...

The JSON array has a built-in feature that automatically generates unique IDs

I have been attempting to achieve this task for quite some time now, but unfortunately, I am unable to get it right. A post on Stack Overflow got me very close, but the JSON hierarchy requirement for my assignment is proving to be a challenge. Currently, ...

Securing Your Data: How to Protect and Reveal Information with Aes Encryption in C#

I am attempting to store an encrypted string as a byte array in an SQL database, but I seem to be encountering some issues. Here is the code snippet: private void loginBtn_Click(object sender, EventArgs e) { try { string ...

Transferring variables from the $(document).ready(function(){}) to the $(window).load(function(){} allows for seamless and

Just think about if I successfully create percent_pass at the time of document.ready, how can I transfer that variable to window.load? $(document).ready(function() { jQuery(function() { var ques_count = $('.question-body').length; va ...

What is the best way to allow someone to chain callback methods on my custom jQuery plugin?

My goal is to enhance the functionality of jQuery.post() by implementing a way to check the response from the server and trigger different callbacks based on that response. For instance: $("#frmFoo").postForm("ajax") .start(function () { showSpinner( ...

The paragraph text should dynamically update upon clicking a button based on JavaScript code, however, the text remains unchanged despite attempts to modify it

I recently started learning JavaScript and wanted to update the content of a paragraph when a button is clicked. However, I encountered an issue where this functionality doesn't seem to work. <body> <p id="paragraph">Change Text on cl ...

Guide to forming an array by extracting specific properties from a nested JSON array using javascript

Currently, I have this list: list = { id: 1, arr: [ {index : 1 , description: "lol" , author: "Arthur"}, {index : 2 , description: "sdadsa" , author: "Bob"}, {index : 3 , desc ...

Is it possible to trim a video using HTML code?

I am trying to find a way to crop a video using HTML 5. <video id="glass" width="640" height="360" autoplay> <source src="invisible-glass-fill.mp4" type="video/mp4"> </video> Currently, the video has a resolution of 640x360. However ...

Tips for dynamically adjusting an iframe's content size as the browser window is resized

Currently, I am in the process of building a website that will showcase a location on a map (not Google Maps). To achieve this, I have utilized an iframe to contain the map and my goal is for the map to adjust its width based on the width of the browser wi ...

Expandable full-width JavaScript accordion for seamless navigation

Currently, I am working on a simple on-page JavaScript application that consists of multiple data pages within one main page. My goal is to create a horizontal accordion effect where clicking on headers on either side will smoothly switch between the diffe ...

After a certain time has passed, an event will occur once a div element has been assigned

Is there a way to show div2 only after div1 has been given the '.selected' class for a set duration, and then hide it again when div1 loses the '.selected' class? What would be the most efficient approach to achieve this? ...

Modify select options using JavaScript without losing the selected choice

I am attempting to update the options list of a select element using JavaScript and jQuery while retaining previously selected values. Below is the code I am using: var temp = $('#SelectName').chosen().val(); select = document.getEleme ...

Utilize custom SMTP with JavaScript to dispatch emails

I'm wondering if it is possible to send emails using just JavaScript (I am working on a PhoneGap app). I envision a scenario where I can connect to a specific SMTP server with a login and password, and then send emails using that connection. I have al ...

The dimensions of the box are not predetermined by the size of the photo

I'm attempting to develop a photo gallery that emulates the style of (using the Unsplash API -> ) However, the size of the container box does not adjust properly with the photos. https://i.sstatic.net/1PAQF.jpg <div className="imageGrid_ ...

Using `await` is only permitted in an asynchronous function within Node.js

I've been working with node and express to develop a server for my application. Here is a snippet of my code: async function _prepareDetails(activityId, dealId) { var offerInfo; var details = []; client.connect(function(err) { assert.equ ...

Handle Ajax requests to prevent multiple submissions upon clicking

Seeking a solution to avoid multiple requests when the user clicks on the login or register button. The code provided below is not functioning as expected; it works fine the first time but then returns false. $('#do-login').click(function(e) { ...

Assigning a class to a table row does not produce any changes

When a user clicks on a table, I am attempting to achieve two tasks using pure Javascript: Retrieve the row number (this functionality is working) Change the background color of the row Below is my current code snippet: document.querySelector('#t ...

AngularJS variable assignment with HTTP GET operation

The angular filter I have set up is functioning perfectly: categorieFilter = angular.module("categorieFilter", []) categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){ $scope.search = ""; $scope.products = []; $ ...

Issue with the demo code for Vue Stripe Checkout

As I delve into the world of Vue-Stripe-Checkout, I encountered a snag right from the start with the demo code provided. The issue arises when utilizing the Vue Stripe Elements component. Has anyone else experienced this problem? There are no errors displa ...