Enhancing the elements in a current array of arrays

I am in the process of creating an array structured like this var qwe = [[a,b],[c],[d]], where a and b serve as identifiers.

The values for a - d are being extracted from the DOM. Currently, my JavaScript code is functioning as intended, but I aim to merge similar arrays based on their identifiers. Running the code below results in:

qwe =[
[100,200],[3],[2],  
[200, 300],[12],[4],    
[100,200],[2],[6]
]

However, my goal is to combine the arrays with matching identifiers so that the final array appears as follows (based on the previous example):

qwe =[
[100,200],[5],[8],
[200, 300],[12],[4]
]

HTML

<table name="tab" id="tab">
  <tr>
    <th>ID</th>
    <th>Location</th>
    <th>Value</th>
    <th>Other</th>
  </tr>
  <tr>
    <td><input name="itinValue" value="100"></td>
    <td><input name="location" value="200"></td>
    <td><input name="num" value='3'></td>
    <td><input name="other" value='2'></td>
  </tr>
  <tr>
    <td><input name="itinValue" value="200"></td>
    <td><input name="location" value="300"></td>
    <td><input name="num" value='12'></td>
    <td><input name="other" value='4'></td>
  </tr>
  <tr>
    <td><input name="itinValue" value="100"></td>
    <td><input name="location" value="200"></td>
    <td><input name="num" value='2'></td>
    <td><input name="other" value='6'></td>
  </tr>
</table>

JavaScript

var table = document.querySelectorAll('[name="itinValue"]');
var qwe = [];

for(var i = 0; i < table.length; i++) {
  var a = document.getElementsByName('itinValue')[i].value;
  var b = document.getElementsByName('location')[i].value;
  var c = document.getElementsByName('num')[i].value;
  var d = document.getElementsByName('other')[i].value;
  var x = [[a,b],[c],[d]];

  //Compare, find, add logic goes here

  //if identifiers do not exist
  qwe.push(x);

}

This fiddle demonstrates my example and correctly outputs the HTML as well: https://jsfiddle.net/3oge7wxg/125/

Answer №1

If you're looking for an associative array, known as a "dict" in Python, where keys are paired with values ([a,b] and [c,d], respectively), you can achieve the same functionality in JavaScript using objects.

To learn more about this concept, check out the following resources:

  • JavaScript Associative Arrays Demystified
  • JavaScript Basics: How to create a Dictionary with Key/Value pairs

Answer №2

To enhance efficiency, I recommend utilizing objects and creating a composite key:

var table = document.querySelectorAll('[name="itinValue"]');
var qwe = {};

for(var i = 0; i < table.length; i++) {
  var a = document.getElementsByName('itinValue')[i].value;
  var b = document.getElementsByName('location')[i].value;
  var c = new Number(document.getElementsByName('num')[i].value);
  var d = new Number(document.getElementsByName('other')[i].value);

  var key = a + "_" + b;

  previousValue = qwe[key];
  qwe[key] = previousValue ? [previousValue[0] + c, previousValue[1] + d] : [c, d];

}

You can easily convert this structure to an array of your preference by following this pattern:

Object.keys(qwe).map(key => [key.split("_")].concat(qwe[key]));

Explore the code snippet on JSFiddle here

Note: Adjusted Number constructors and included a link to the fiddle for reference

Answer №3

Some important points to note from your inquiry are:

  • You are iterating through an array of data.
  • You are storing data based on a tuple key.
  • The option to add values where the key matches.
  • If the variables a, b, c, and d are strings instead of ints, you may need to use parseInt(). This can be achieved by checking if the current type is a string and converting it if necessary.

Since tuples are not directly supported in JavaScript, one workaround is shown below.

var m = {};
var table = document.querySelectorAll('[name="itinValue"]');
for(var i = 0; i < table.length; i++) {

  var a = +document.getElementsByName('itinValue')[i].value;
  var b = +document.getElementsByName('location')[i].value;
  var c = +document.getElementsByName('num')[i].value;
  var d = +document.getElementsByName('other')[i].value;

  var key = a.toString() + "-" + b.toString();
  //creates key = "100-200"
  if (m[key]){
    m[key] = [m[key][0] + c, m[key][1] + d]
  }else{
    m[key] = [c,d]
  }
}

Eventually, your map will have unique keys and a structure like this:

{
  "100-200": [5,8],
  "200-300": [12,4]
}

If needed, you can split the keys later by using map.keys[index].split("-").

This implementation appears clean, but for further refinement, consider transforming it into a class.

Subsequently, the information is stored in qwe. If required, it can be easily converted from a map to a list, depending on the specific implementation goal. The primary distinction usually lies in whether maintaining order is crucial. qwe solely contains this valuable information, and considering your comment about its limitations, it seems that preserving the key data elements—key/tuple and two values—is more essential than strict ordering.

Answer №4

In case you are aware of the number of fields per row, here is an alternative method for fetching your array data.

let newData = {};
let elements = document.querySelectorAll('table#tab input');
for (let i=0; i<elements.length; i+=4) {
    let indexer = i < 4 ? 0 : i;
    let newRow = {
        a: [
            parseInt(elements[indexer].value)
          , parseInt(elements[indexer+1].value)
        ]
        , c: parseInt(elements[indexer+2].value)
        , d: parseInt(elements[indexer+3].value)
    };
    newRow.key = newRow.a.join('_');

    if (newData[newRow.key]) {
        newData[newRow.key][1][0]+=newRow.c;
        newData[newRow.key][2][0]+=newRow.d;
    } else {
        newData[newRow.key] = [newRow.a, [newRow.c], [newRow.d]];
    }
}

console.log( Object.values(newData) );

Answer №5

To update an item, search for it first and if not found, add the new array.

var table = document.querySelectorAll('[name="itinValue"]'),
    qwe = [],
    a, b, c, d, i,
    item;

for (i = 0; i < table.length; i++) {
    a = +document.getElementsByName('itinValue')[i].value;
    b = +document.getElementsByName('location')[i].value;
    c = +document.getElementsByName('num')[i].value;
    d = +document.getElementsByName('other')[i].value;

    item = qwe.find(([[l, r]]) => l === a && r === b);
    if (item) {
        item[1][0] += c;
        item[2][0] += d;
    } else {
        qwe.push([[a, b], [c], [d]]);
    }
}

console.log(qwe);
<table name="tab" id="tab">
  <tr>
    <th>ID</th>
    <th>Location</th>
    <th>Value</th>
    <th>Other</th>
  </tr>
  <tr>
    <td><input name="itinValue" value="100"></td>
    <td><input name="location" value="200"></td>
    <td><input name="num" value='3'></td>
    <td><input name="other" value='2'></td>
  </tr>
  <tr>
    <td><input name="itinValue" value="200"></td>
    <td><input name="location" value="300"></td>
    <td><input name="num" value='12'></td>
    <td><input name="other" value='4'></td>
  </tr>
  <tr>
    <td><input name="itinValue" value="100"></td>
    <td><input name="location" value="200"></td>
    <td><input name="num" value='2'></td>
    <td><input name="other" value='6'></td>
  </tr>
</table>

Modified version with Map.

var table = document.querySelectorAll('[name="itinValue"]'),
    qwe = [],
    a, b, c, d, i,
    item
    map = new Map;

for (i = 0; i < table.length; i++) {
    a = +document.getElementsByName('itinValue')[i].value;
    b = +document.getElementsByName('location')[i].value;
    c = +document.getElementsByName('num')[i].value;
    d = +document.getElementsByName('other')[i].value;

    item = map.get([a, b].join('|'));
    if (item) {
        item[1][0] += c;
        item[2][0] += d;
    } else {
        item = [[a, b], [c], [d]]
        map.set([a, b].join('|'), item);
        qwe.push(item);
    }
}

console.log(qwe);
<table name="tab" id="tab">
  <tr>
    <th>ID</th>
    <th>Location</th>
    <th>Value</th>
    <th>Other</th>
  </tr>
  <tr>
    <td><input name="itinValue" value="100"></td>
    <td><input name="location" value="200"></td>
    <td><input name="num" value='3'></td>
    <td><input name="other" value='2'></td>
  </tr>
  <tr>
    <td><input name="itinValue" value="200"></td>
    <td><input name="location" value="300"></td>
    <td><input name="num" value='12'></td>
    <td><input name="other" value='4'></td>
  </tr>
  <tr>
    <td><input name="itinValue" value="100"></td>
    <td><input name="location" value="200"></td>
    <td><input name="num" value='2'></td>
    <td><input name="other" value='6'></td>
  </tr>
</table>

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

Toggle the visibility of a table row depending on the selected value of a Radio button

I have a jQuery script that I am working on, which toggles the visibility of table rows based on the selection of radio buttons. The current code functions properly when a radio button is clicked, but I would like to enhance it to automatically show or hid ...

What is the reason behind the failure of executing "this.$refs.inputField.focus()"?

I've set up an input field with a ref="inputField" as shown below: <input ref="inputField"> <button @click="btn">Click</button> When the button is clicked, I want the input field to receive focus. Here& ...

Is it possible to reorganize the JavaScript modules created by the TypeScript compiler?

In my TypeScript project, the structure resembles that of a typical Maven Java project. Here is an overview of how the project is organized: *.js file for commonjs/webpack, system, and amd.</p> For commonjs/webpack, I utilize tsc with tsconfig.jso ...

The execution of async.each does not complete successfully

I'm facing an issue with a simple function that retrieves the word count from a URL. The script runs smoothly with a low number of URLs, limiting the async to 4 at a time. I keep an eye on my RAM and CPU usage, but they never come close to maxing out. ...

"Utilizing the Bootstrap framework to enhance the functionality

I have a bootstrap table containing data that needs to be edited, with certain fields not displayed in the table. To enable editing, I have added an edit button to each row along with a modal form. The button successfully loads the modal form without any ...

Is there a way to efficiently process multipart/formdata, application/json, and text/plain within a single Express handler?

Operating an express demo server that mirrors the client's POST requests back to it is a part of an educational practice. In this exercise, the client makes a POST request using the fetch API, like so: fetch('http://localhost:5000/', { m ...

Having issues with the onclick() function not functioning properly with Jquery?

Yesterday, I successfully integrated some Jquery code into my website. However, when I attempted to add more code today for a new feature, everything seemed to stop working. Even the code that was functioning perfectly yesterday has now ceased to work. The ...

Issue with RxDom: malfunctioning after creation of new ID

Currently, I am utilizing Reactive Extension DOM to listen for events from the DOM. Below is a snippet of my code: var input = document.getElementById('test_id'); var source = Rx.DOM.change(input); var subscription = source.subscribe( fu ...

Avoiding the use of numbers in v-if in Vue.js

My website features a left menu that displays different content based on the selected menu's ID. However, I currently have === 0 and === 1 in the v-if statement, and I'm looking for a way to avoid manually inputting these numbers. <template& ...

An assortment of the most similar values from a pair of arrays

I am seeking an algorithm optimization for solving a specific problem that may be challenging to explain. My focus is not on speed or performance, but rather on simplicity and readability of the code. I wonder if someone has a more elegant solution than mi ...

Malfunction in triggering events within an Ajax Magnific popup feature

I'm trying to load a page within a magnific popup using ajax: $("#operator").magnificPopup({ delegate: 'a.edit', mainClass: 'mfp-fade', closeBtnInside: true, removalDelay: 300, closeOnContentClick: false, t ...

What is the best way to invoke a class using variables from an array in PHP?

Can you create a class that takes parameters dynamically from an array instead of hardcoding them? $array = array("first","second","third"); This is how the class should be instantiated: $class = new class("first","second","third"); ...

Embrace AngularJS: Employ the ".then" method and retrieve the response

In order to send a http request and receive the response of this request, I am trying to implement a mechanism where if the data is successfully saved, I can retrieve database information, and if it fails to save, I can track errors. To achieve this, I pla ...

What is the best method for circumventing an express middleware?

I am currently working on an express application that utilizes several express routes, such as server.get('*' , ... ) to handle common operations like authentication, validation, and more. These routes also add extra information to the respon ...

Is it possible to dynamically change the object name using $.ajax function and pass it as a

I'm attempting to parse multiple JSON files into different objects. Here is my approach: function downloadDataSave (targetObject) { // DOWNLOAD CALCULATION BACKUP var filename, response; filename = targetObject.name + '.json' ...

What is causing express.js not to authenticate properly?

I'm currently in the process of developing a server application using node.js, which is up and running on localhost:8080. As I attempt to make a login request, I've encountered an issue where one method works while the other fails. My suspicion i ...

ReactJS: Error - Attempting to convert an undefined or null value to an object is not

Encountering an issue with my Beach component, which is throwing the following error: TypeError: Cannot convert undefined or null to object ResortDetail C:/Users/JS/Desktop/MERN/KR/frontend/src/screens/Beach.js:33 30 | <p>{description}< ...

Using a React button to sort through an array

Hey there, I'm currently working on an app that filters a list based on user input. The idea is to click on buttons to exclude users with specific letters in their names. However, the code I have right now isn't functioning properly. Any assistan ...

Refreshing the View based on ng-model modifications in AngularJS

Is there a way to update an array linked to my ng-model after clicking a button without having to bind them? The issue arises because the data is being selected from a list. I want the data to be updated as soon as the button is clicked, without needing to ...

Is it possible to dynamically choose between GET and POST methods for an AJAX request?

Consider the following code snippet which intercepts the form submission event from two different forms. $("#aaa, #bbb").submit(function(e) { e.preventDefault(); var form = $(this); var url = form.attr('action'); $.ajax({ ...