The nested for loop that I am using is producing repeated values

The objective of this operation is to input:

[{lang: 'English', proficiency: 'Elementary Proficiency'}, {lang: 'Spanish', proficiency: 'Full Professional Proficiency'}]
.

Then, the goal is to output:

[{level: 1, lang: 'English', proficiency: 'Elementary Proficiency'}, { level:3, lang: 'Spanish', proficiency: 'Full Professional Proficiency'}]
.

However, the current output is:

[{level:3, lang: 'Spanish', proficiency: 'Full Professional Proficiency}, {level:3, lang: 'Spanish', proficiency: 'Full Professional Proficiency}]
. Any suggestions? Thank you.

updateSort(exObj) {
      let userprof = []
      let lng = []

      const proficiencies = [
        { level: 1, name: 'Elementary Proficiency' },
        { level: 2, name: 'Limited Working Proficiency' },
        { level: 3, name: 'Full Professional Proficiency' },
        { level: 4, name: 'Native Bilingual Proficiency' }
      ]

      for(let v in exObj) {
        userprof.push(exObj[v].proficiency);
        lng.push(exObj[v].lang);
      }

      let findMaxProficiency = (proficiencies, userprof) => {
          const arr = [];
          const ob = {};

          let found = false;
          for (const prof of proficiencies) {
            for (const user of userprof) {
              if (found) found = false
              for (const l of lng) {
                if (prof.name === user) {
                  ob.level = qual.level
                  ob.proficiency = qual.name
                  ob.lang = l
                  arr.push(ob);
                  found = true
                  break
                }
              }
            }
          }
          console.log("PROFICIENCIES FOUND: " + JSON.stringify(arr))
      }
      findMaxProficiency(proficiencies, userqual);
    }

Answer №1

It seems that utilizing the map function provides a more straightforward solution to this problem.

const levels = [
  { number: 1, type: 'Basic Level' },
  { number: 2, type: 'Intermediate Level' },
  { number: 3, type: 'Advanced Level' },
  { number: 4, type: 'Expert Level' }
];

const languages = [
  { name: 'English', level: 'Basic Level' },
  { name: 'Spanish', level: 'Advanced Level' }
];


const result = languages.map((language) => {
  const proficiencyLevel = levels.find(l => l.type === language.level);
  if (proficiencyLevel) {
    language.number = proficiencyLevel.number;
  }
  return language;
});

console.log(result);

Answer №2

To successfully break out of all levels of the for loop, make sure to include additional break statements. If you only break out of the deepest level, the next loop will not exit and will start over. This can lead to unintended behavior where your boolean variable gets reset with the instruction if (found) found = false, causing the same tasks to be repeated.

for (const prof of proficiencies) {
    for (const user of userprof) {
        if (found) found = false
        for (const l of lng) {
            if (prof.name === user) {
                ob.level = qual.level
                ob.proficiency = qual.name
                ob.lang = l
                arr.push(ob);
                found = true
                break
            }
        }
        if (found) break;
    }
    if (found) break;
}

Answer №3

By converting your skills array into an object, you can simplify the process using just one map() function.

const input = [{language: 'French', proficiency: 'Intermediate Proficiency'}, {language: 'German', proficiency: 'Advanced Proficiency'}];

const proficiencies = {
        'Elementary Proficiency': 1,
        'Limited Working Proficiency': 2,
        'Full Professional Proficiency': 3, 
        'Native Bilingual Proficiency': 4
      }

const result = input.map(obj => ({level: proficiencies[obj.proficiency],...obj}));

console.log(result);

Answer №4

If you're looking for a simpler solution to your issue, consider approaching it from a different angle. Instead of using multiple loops, you can utilize a Map structure (similar to an object with key-value pairs accessible via .get(key)). Construct the map from the proficiency array by employing the Map constructor. This constructor requires an array of

[[key1, value1], [key2, value2], ...]
pairs that can be created using the .map() method on your array. The resulting map will resemble this:

"Elementary Proficiency" => 1
"Limited Working Proficiency" => 2
"Full Professional Proficiency" => 3
"Native Bilingual Proficiency" => 4

The numbers represent values obtainable from the map using .get(proficiencyName). Once established, simply update all objects in your original array to include a level property. Achieve this by utilizing .map() again to construct new objects with current properties (employing the spread syntax ...), along with an additional level property obtained by referencing the proficiency level in the Map created earlier:

const arr = [{lang: 'English', proficiency: 'Elementary Proficiency'}, {lang: 'Spanish', proficiency: 'Full Professional Proficiency'}];
const proficiencies = [ { level: 1, name: 'Elementary Proficiency' }, { level: 2, name: 'Limited Working Proficiency' }, { level: 3, name: 'Full Professional Proficiency' }, { level: 4, name: 'Native Bilingual Proficiency' } ];

const levelLookUp = new Map(proficiencies.map(o => [o.name, o.level]));
const result = arr.map(obj => ({level: levelLookUp.get(obj.proficiency), ...obj}));

console.log(result);

Creating a Map first enhances performance, especially with larger input arrays, as it involves looping over the proficiencies array and the input array independently only once, avoiding potential performance issues associated with nested loops.

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

What is the best way to send a string and a component as a prop?

When passing a component, it works fine like this: <CardTitle title={this.props.post.title} subtitle={ <Link to={this.props.post.author}>{this.props.post.author}</Link> } /> However, when trying to pass both a component and string t ...

jQuery document.ready function not triggering as expected (even with jQuery included)

After conducting thorough research on Google and Stack Overflow, I noticed a common issue with incorrectly including jQuery. However, I made sure to include it correctly. In my header, I have the following code: <!DOCTYPE html PUBLIC "-//W3C//DTD ...

Obtaining template attributes in CKEditor: A guide

I have been working with the template plugin in CKEditor to load predefined templates. Each template is defined as follows: templates: [ { title: "Quickclick 1", image: "template1.png", description: "Quickclick 1 template", html_et: "& ...

Are there any AJAX tools or packages in Node.js Express for connecting (posting/getting) with other servers and retrieving data?

Can someone please guide me on how to utilize ajax in node.js to send and receive JSON data from another server? Is there a package available that allows for this functionality, similar to jQuery's $.ajax, $.post, or $.get methods? ...

Enhance a React component by including additional properties when passing it into another component through props

I have a parent element with a dynamically changing height that I need to pass down to its child elements. To get and set the height of the parent element, I am utilizing a ref. The challenge lies in passing this height value from the parent component to ...

Change a 24-hour time variable to 12-hour time using AngularJS/jQuery technology

I have a value retrieved from the database in a 24-hour time string format. I am seeking a solution to convert this string into a 12-hour clock time using either AngularJS or jQuery. Currently, I am unable to make any changes to the back-end (JAVA) or the ...

Learn how to execute JavaScript code in Selenium without launching a web browser

I am currently using the Selenium API for web scraping on pages that contain JavaScript code. Is there a way to retrieve the code without having to open a web browser? I am still learning how to use this API Is this even feasible? ...

What is the best way to incorporate a table name into a MySQL query using ExpressJs?

My goal is to retrieve the contents of a specific table using this code snippet: let tableName = req.body.login connection.query('SELECT * FROM ?', tableName, (err, rows) => { if (err) throw err res.send(rows) }) However, as tableName ...

Issue with AJAX causing form data not to be passed to controller

Recently, I encountered an issue with a form in my view: <form id="MyForm"> <input type="text" name="myinput" /> <button type="submit" /> </form> In my view's JavaScript code, which is executed upon page load, I have the foll ...

Leveraging react props with the .map method

Imagine having this render function in one of your components. You've passed a changeTid prop function from the parent element. Parent Component: <RequestsList data={this.state.data} changeTid={this.changeTid} /> Child Component: (Using ES6 ...

What is the best way to execute createReadStream(a stream) within a grunt plugin?

Struggling to implement a stream in a grunt plugin? Here's a comparison of code that works as a standalone node script: var fs = require('fs'); var sourceFile = 'testfile.log'; fs .createReadStream(sourceFile) .on(' ...

Utilizing $rootScope in AngularJS as a central data repository

I've come up with an idea for my AngularJS app and I'm curious to know what the AngularJS community thinks about it. Essentially, I'm connecting to a data API and displaying the results on the page. My approach involves creating an AngularJ ...

Generating a three-dimensional sphere from flat coordinates with the help of sine and cosine functions

I am trying to achieve mapping a set of 2D coordinates to a 3D surface of a sphere. To accomplish this, I am starting with an array of xy coordinates. Using the following loops, I am generating 20*20 xy coordinates ranging from 0 to 1 on each axis: var p ...

Extract the content from a widget on a different site

How can I eliminate the specified text shown in the image? https://i.sstatic.net/174fD.png This widget is sourced from an external website. Is it possible to use javascript to wrap a around the text and then remove it using css? It's important to ...

Enhance user experience by implementing an autocomplete feature for a text input field

Can you name the process in which a form is automatically filled using database information without needing to refresh the page? One common example of this technique is seen on platforms like Google or Facebook, where they predict friends you may be searc ...

Inserting a new row into a particular table

I am working on a project where I have a table that displays different exercises. My goal is to allow users to add a new row for each exercise individually. Currently, the snippet below shows how I have implemented this: <!DOC ...

JavaScript, CSS, and HTML - elements that dynamically adjust their size according to the content they hold

Being brand new to web development, I have a task of creating objects that feature text in a box with rounded edges, similar to the image provided. The challenge is that the border size needs to dynamically adjust based on the text size. Restrictions on u ...

React eliminates all white spaces

Presented here is a compilation of various span elements: <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> Accompanied by the CSS style for these elements: span{ bac ...

jQuery Ajax error 403 (unlike XMLHttpRequest)

Recently, I encountered an issue with two Ajax calls in my code. One of the calls was implemented using XMLHttpRequest and the other one using jQuery. Surprisingly, the first call completed successfully without any errors. However, the second call, which s ...

Express.js error: Unexpected closing parenthesis after argument list

Here is a snippet of code that I am having trouble with: doc.image('images/pic_1.jpg', 0, 15, scale: 0.25) .text('Scale', 0, 0) I referred to the official PDFkit documentation at PDFKit documentation However, when I tried this co ...