Fastest way to duplicate an array in JavaScript - slice vs. 'for' loop
There are at least 6 (!) ways to clone an array:
- loop
- slice
- Array.from()
- concat
- spread operator (FASTEST)
- map
A.map(function(e){return e;});
There has been a huuuge BENCHMARKS thread, providing following information:
for blink browsers
slice()
is the fastest method,concat()
is a bit slower, andwhile loop
is 2.4x slower.for other browsers
while loop
is the fastest method, since those browsers don't have internal optimizations forslice
andconcat
.
This remains true in Jul 2016.
Below are simple scripts that you can copy-paste into your browser's console and run several times to see the picture. They output milliseconds, lower is better.
while loop
n = 1000*1000;
start = + new Date();
a = Array(n);
b = Array(n);
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);
slice
n = 1000*1000;
start = + new Date();
a = Array(n);
b = a.slice();
console.log(new Date() - start);
Please note that these methods will clone the Array object itself, array contents however are copied by reference and are not deep cloned.
origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true
Javascript - Fastest way of copying an array portion into another
You could keep unrolling the loop for even slighter increases in performance, but it seems like this is just about as fast as you're going to get it. As Gumbo stated in a comment, try using pre-increment instead of post-increment:
var i = 0x4000>>5 + 1; // loops count
var j = 0x4000 - 1; // write start index
var k = 0x8000 - 1; // read start index
while (--i) { // loop unrolling
dst[++j]=src[++k]; dst[++j]=src[++k];
dst[++j]=src[++k]; dst[++j]=src[++k];
dst[++j]=src[++k]; dst[++j]=src[++k];
dst[++j]=src[++k]; dst[++j]=src[++k];
//8
...
What's the fastest way to loop through an array in JavaScript?
After performing this test with most modern browsers:
https://jsben.ch/wY5fo
Currently, the fastest form of loop (and in my opinion the most syntactically obvious).
A standard for-loop with length caching
var i = 0, len = myArray.length;
while (i < len) {
// your code
i++
}
I would say, this is definitely a case where I applaud JavaScript engine developers. A runtime should be optimized for clarity, not cleverness.
A copy of an array changes the original array even with slice
You aren't changing the array, you are mutating the objects within the array. You don't want that.
const myObj = {
x:1,
y:1
};
const myArray = [myObj];
const myNewArray = [...myArray];
myNewArray[0].x = 2;
console.log(myArray[0].x); // 2!!!!!
If you are changing an object within the array and you don't want it to mutate, then do this:
const myObj = {
x:1,
y:1
};
const myArray = [myObj];
// helper function that will perform a mutation at a given position
// and ignore all other positions
const mutateObjectAtPosition = (pos,mutation) => [...myArray].map((o,i) => i === pos ? mutation(o) : o)
// at position 0, return a **new object** with x set to 2
const myNewArray = mutateObjectAtPosition(0,(o) => ({...o,x:2}));
console.log(myNewArray !== myArray); // true, different references
console.log(myNewArray[0].x); // 2
console.log(myArray[0].x); // 1
Javascript array copying, concat vs slice, which one is better?
For clarity, you should use the method that is the documented method of taking a copy of an array (or portion thereof):
var c2 = a.slice(0);
On any decent browser the performance difference will be negligible, so clarity should be the deciding factor.
loop through slices and amend into a 2D array
You can achieve the same without using extra variables
package main
import (
"fmt"
"log"
"strings"
"golang.org/x/exp/slices"
)
func main() {
var codeSlices = []string{
"# INPUTS",
"",
"input CreateUserInput {",
" username: String!",
" email: String!",
" password: String!",
"}",
"",
"input AuthUserInput {",
" user: String!",
" password: String!",
" code: String",
"}",
"",
"input RefreshTokensInput{",
" refreshToken: String!",
"}",
"",
"input VerifyEmailInput {",
" token: String!",
"}",
"",
"# OBJECTS",
"",
}
//Check for boundaries
inputStart := slices.Index(codeSlices, "# INPUTS") //Use built-in functions for the search
if inputStart == -1 {
log.Fatal("# INPUTS not found")
}
objectStart := slices.Index(codeSlices, "# OBJECTS")
if objectStart == -1 {
log.Fatal("# OBJECTS not found")
}
inputStart = 0
var inputs [][]string
for i := inputStart + 2; i < objectStart-1; i++ {
if idx := strings.Index(codeSlices[i], "{"); idx > 0 {
inputStart = i
continue
}
if idx := slices.Index(codeSlices[inputStart:], "}"); inputStart > 0 {
inputs = append(inputs, codeSlices[inputStart:i+idx])
inputStart = 0
}
}
if inputStart > 0 {
log.Fatal("Mismatch inputs")
}
fmt.Printf("%#v\n", inputs)
}
Playground
Is there a method to add and an arry of objects to the end of an array of objects without makeing a for loop?
I would use the spread syntax ...
const obj1 = [{"d": "1", "t": "1"}, {"d": "2", "t": "2"}]
const obj2 = [{"d": "3", "t": "3"}, {"d": "4", "t": "4"}]
const obj3 = [...obj1, ...obj2]
console.log(obj3)
Related Topics
How to Declare a Namespace in JavaScript
Location of Parenthesis For Auto-Executing Anonymous JavaScript Functions
How to Parse CSV Data With JavaScript
How to Add Two Strings as If They Were Numbers
Use Basic Authentication With Jquery and Ajax
Updating Address Bar With New Url Without Hash or Reloading the Page
Async/Await Implicitly Returns Promise
Remove Empty Elements from an Array in JavaScript
Rails 4: How to Use $(Document).Ready() With Turbo-Links
When Are You Supposed to Use Escape Instead of Encodeuri/Encodeuricomponent
Jquery Animate Backgroundcolor
What Are Valid Date Time Strings in JavaScript
Why Does JavaScript Only Work After Opening Developer Tools in Ie Once
How to Round to At Most 2 Decimal Places, If Necessary
What Is the Purpose of a Self Executing Function in JavaScript