简体   繁体   中英

Using javascript, what is an efficient way of changing the length of elements in a jagged array?

I am trying to find an efficient way of changing the length of an array and the elements within the array. For example, if I have

var arr = [["Name", "Age", "Lightsaber Color"], ["Luke Skywalker", "22", "Green"], ["Yoda", "900", "Green"], ["Obi Wan Kenobi", "59", "Blue"]]

I want to end up with

var arr = [["Name", "Age"], ["Luke Skywalker", "22"], ["Yoda", "900"]]

I have written some code to do this, but I want to ensure that the way I am changing the length of the nested arrays (for lack of a better term) is as efficient as possible.

I have:

var arr = [["Name", "Age", "Lightsaber Color"], ["Luke Skywalker", "22", "Green"], ["Yoda", "900", "Green"], ["Obi Wan Kenobi", "59", "Blue"]]
arr.length = 3; // Removes the Obi Wan entry
console.log(arr);
for(var i = 0; i < arr.length; i++){
        arr[i].length = 2 // Removes lightsaber color
};
console.log(arr)

The code I'm wanting to hopefully optimize is the for loop. I'll be working with much larger datasets. Thanks

The code I'm wanting to hopefully optimize is the for loop.

What you're doing is already as efficient as it's going to get, if you mean runtime efficiency. Anything using other things (like slice or map ) is going to be slower.


Note that it's really unlikely to matter . Unless you've already identified that this loop is a performance blocker, don't worry about it. If you have identified that this is a performance blocker, the array(s) must be really big . :-) Even if you're dealing with 100,000 arrays, I wouldn't think this would take any significant time.

Let's find out:

 const now = performance.now ? performance.now.bind(performance) : Date.now.bind(Date); // Create an array with 110k entries, each being five entries long. const arr = Array.from({length:110000}, () => ["a", "b", "c", "d", "e"]); // Start timing const start = performance.now(); // Cut it down to 100k entries arr.length = 100000; // Trim them to two entries for (const entry of arr) { entry.length = 2; } // Done timing const elapsed = now() - start; console.log("Elapsed: " + elapsed + "ms");

I get about 20ms on my workstation using Brave (like Chrome, uses V8 as the JavaScript engine).

This is not a rigorous benchmark , but it gives us an idea...

Just a minor improvement, but sometimes Array.prototype.splice is faster than setting the array's length to truncate an array:

 var arr = [["Name", "Age", "Lightsaber Color"], ["Luke Skywalker", "22", "Green"], ["Yoda", "900", "Green"], ["Obi Wan Kenobi", "59", "Blue"]] arr.splice(3); // Removes the Obi Wan entry console.log(arr); for(var i = 0; i < arr.length; i++){ arr[i].splice(2) // Removes lightsaber color } console.log(arr);

For a benchmark comparing both versions, see http://jsben.ch/BmvNj .

You can use array.splice :

arr[i] = arr[i].splice(0, 2);

Try this:

 var arr = [["Name", "Age", "Lightsaber Color"], ["Luke Skywalker", "22", "Green"], ["Yoda", "900", "Green"], ["Obi Wan Kenobi", "59", "Blue"]] arr.length = 3; // Removes the Obi Wan entry console.log(arr); for(var i = 0; i < arr.length; i++){ arr[i] = arr[i].splice(0, 2); }; console.log(arr)

Well, you can do this:

arr.forEach(function(item) { item.splice(-1) });

splice(-1) modifies the original array, deleting the last item on it

You can combine Array.map with Array.slice :

 let arr = [["Name", "Age", "Lightsaber Color"], ["Luke Skywalker", "22", "Green"], ["Yoda", "900", "Green"], ["Obi Wan Kenobi", "59", "Blue"]]; let result = arr.map(person => person.slice(0, 2)); console.log(result);

Here is a simple and readable way of your requirements.

var arr = [["Name", "Age", "Lightsaber Color"], ["Luke Skywalker", "22", "Green"], ["Yoda", "900", "Green"], ["Obi Wan Kenobi", "59", "Blue"]]
    for(var i=0; i< arr.length;i++){
      arr[i].splice(-1, 1)
    }
    console.log(arr);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM