วิธีการขยายอาร์เรย์ JavaScript ที่มีอยู่ด้วยอาร์เรย์อื่นโดยไม่ต้องสร้างอาร์เรย์ใหม่


971

ดูเหมือนจะไม่มีวิธีที่จะขยายอาร์เรย์ JavaScript ที่มีอยู่กับอาร์เรย์อื่นเช่นเพื่อเลียนแบบextendวิธีการของ Python

ฉันต้องการบรรลุสิ่งต่อไปนี้:

>>> a = [1, 2]
[1, 2]
>>> b = [3, 4, 5]
[3, 4, 5]
>>> SOMETHING HERE
>>> a
[1, 2, 3, 4, 5]

ฉันรู้ว่ามันมีa.concat(b)วิธีการ แต่มันสร้างอาเรย์ใหม่แทนที่จะขยายออกไปอย่างแรก ฉันต้องการอัลกอริทึมที่ทำงานอย่างมีประสิทธิภาพเมื่อaมีขนาดใหญ่กว่าอย่างมากb(เช่นที่ไม่ได้คัดลอกa)

หมายเหตุ:นี่ไม่ใช่สิ่งที่ซ้ำกันของวิธีผนวกบางสิ่งเข้ากับอาร์เรย์ - เป้าหมายที่นี่คือการเพิ่มเนื้อหาทั้งหมดของอาเรย์หนึ่งไปยังอีกอาเรย์และเพื่อทำมัน "ในสถานที่" คือโดยไม่ต้องคัดลอกองค์ประกอบทั้งหมดของอาเรย์ขยาย


5
จากความคิดเห็นของ @ Toothbrush บนคำตอบ: a.push(...b). มันคล้ายกับแนวคิดของคำตอบที่ได้รับการปรับปรุง แต่สำหรับ ES6
tscizzle

คำตอบ:


1498

.pushวิธีสามารถใช้ข้อโต้แย้งหลาย คุณสามารถใช้ตัวดำเนินการสเปรดเพื่อส่งผ่านองค์ประกอบทั้งหมดของอาร์เรย์ที่สองเป็นอาร์กิวเมนต์ไปที่.push:

>>> a.push(...b)

หากเบราว์เซอร์ของคุณไม่รองรับ ECMAScript 6 คุณสามารถใช้.applyแทน:

>>> a.push.apply(a, b)

หรือบางทีถ้าคุณคิดว่ามันชัดเจนกว่า:

>>> Array.prototype.push.apply(a,b)

โปรดทราบว่าการแก้ปัญหาเหล่านี้ทั้งหมดจะล้มเหลวโดยมีข้อผิดพลาดล้นล้นหากอาร์เรย์bยาวเกินไป (ปัญหาเริ่มต้นที่ 100,000 องค์ประกอบขึ้นอยู่กับเบราว์เซอร์)
หากคุณไม่สามารถรับประกันได้ว่าbสั้นพอคุณควรใช้เทคนิคแบบวนรอบมาตรฐานที่อธิบายไว้ในคำตอบอื่น ๆ


3
ฉันคิดว่านี่เป็นทางออกที่ดีที่สุดของคุณ สิ่งอื่นใดที่เกี่ยวข้องกับการทำซ้ำหรือการออกแรงอีกครั้งของการใช้ ()
30432 Peter Bailey

44
คำตอบนี้จะล้มเหลวถ้า "b" (อาร์เรย์ที่จะขยาย) มีขนาดใหญ่ (> 150000 รายการโดยประมาณใน Chrome ตามการทดสอบของฉัน) คุณควรใช้ a for for loop หรือใช้ฟังก์ชัน "forEach" บน inbuilt กับ "b" ดูคำตอบของฉัน: stackoverflow.com/questions/1374126/…
jcdude

35
@Deqing: pushวิธีการของอาร์เรย์สามารถใช้จำนวนอาร์กิวเมนต์ใด ๆ ซึ่งจะถูกผลักไปทางด้านหลังของอาร์เรย์ ดังนั้นa.push('x', 'y', 'z')การโทรที่ถูกต้องที่จะขยายa3 องค์ประกอบคือ applyเป็นวิธีการของฟังก์ชั่นใด ๆ ที่ใช้อาร์เรย์และใช้องค์ประกอบของมันราวกับว่าพวกเขาทั้งหมดได้รับอย่างชัดเจนว่าเป็นองค์ประกอบตำแหน่งให้กับฟังก์ชั่น ดังนั้นa.push.apply(a, ['x', 'y', 'z'])จะขยายอาร์เรย์ 3 องค์ประกอบด้วย นอกจากนี้applyใช้บริบทเป็นอาร์กิวเมนต์แรก (เราส่งต่อที่aนั่นเพื่อผนวกเข้าด้วยa)
DzinX

หมายเหตุ: ในสถานการณ์นี้ค่าส่งคืนแรกไม่ใช่ [1,2,3,4,5] แต่ 5 ในขณะที่ == [1,2,3,4,5] ในภายหลัง
jawo

1
อีกเล็กน้อยน้อยสับสน (และไม่มากอีกต่อไป) [].push.apply(a, b)การภาวนาจะเป็น:
niry

259

อัปเดตปี 2561 : คำตอบที่ดีกว่าคือคำตอบใหม่ของฉัน : a.push(...b). อย่าโหวตขึ้นอีกแล้วเพราะมันไม่เคยตอบคำถามจริงๆ แต่มันเป็นแฮ็คปี 2015 ที่ได้รับความนิยมอย่างมากใน Google :)


สำหรับผู้ที่เพียงแค่ค้นหา "อาร์เรย์ JavaScript ขยาย" Array.concatและมาถึงที่นี่คุณสามารถใช้งานได้เป็นอย่างดี

var a = [1, 2, 3];
a = a.concat([5, 4, 3]);

Concat จะส่งคืนสำเนาของอาร์เรย์ใหม่เนื่องจากไม่ต้องการเริ่มต้นเธรด แต่คุณอาจไม่สนใจ (แน่นอนสำหรับการใช้งานส่วนใหญ่สิ่งนี้จะใช้ได้)


นอกจากนี้ยังมีน้ำตาล ECMAScript 6 ที่ดีสำหรับสิ่งนี้ในรูปแบบของผู้ดำเนินการแพร่กระจาย:

const a = [1, 2, 3];
const b = [...a, 5, 4, 3];

(นอกจากนี้ยังคัดลอก)


43
คำถามนี้ระบุชัดเจนว่า: "โดยไม่ต้องสร้างอาร์เรย์ใหม่"
เหี่ยวแห้ง

10
@Wilt: นี่เป็นความจริงคำตอบบอกว่าทำไม :) นี่เป็นครั้งแรกที่ Google ได้รับความนิยมเป็นเวลานาน โซลูชั่นอื่น ๆ ก็น่าเกลียดต้องการบางสิ่งบางอย่างที่ดีและดี แม้ว่าทุกวันนี้สิ่งarr.push(...arr2)ใหม่กว่าและดีกว่าและคำตอบที่ถูกต้องทางเทคนิค (tm) สำหรับคำถามนี้
odinho - Velmont

7
ฉันได้ยินคุณ แต่ฉันค้นหา"javascript ผนวกอาร์เรย์โดยไม่ต้องสร้างอาร์เรย์ใหม่"จากนั้นเป็นเรื่องน่าเศร้าที่เห็นว่าคำตอบ upvote 60 ครั้งที่สูงขึ้นไม่ตอบคำถามจริง;) ฉันไม่ได้ลงคะแนน เนื่องจากคุณทำให้ชัดเจนในคำตอบของคุณ
เหี่ยวแห้ง

202

คุณควรใช้เทคนิคการวนรอบ คำตอบอื่น ๆ ในหน้านี้ซึ่งอิงจากการใช้.applyอาจล้มเหลวสำหรับอาร์เรย์ขนาดใหญ่

การใช้ลูปที่ค่อนข้างเป็นวงสั้นคือ:

Array.prototype.extend = function (other_array) {
    /* You should include a test to check whether other_array really is an array */
    other_array.forEach(function(v) {this.push(v)}, this);
}

จากนั้นคุณสามารถทำสิ่งต่อไปนี้:

var a = [1,2,3];
var b = [5,4,3];
a.extend(b);

คำตอบของ DzinX (ใช้ push.apply) และ.applyวิธีการอื่น ๆ นั้นล้มเหลวเมื่ออาร์เรย์ที่เราต่อท้ายมีขนาดใหญ่ (การทดสอบแสดงให้เห็นว่าสำหรับฉันที่มีขนาดใหญ่คือ> 150,000 รายการโดยประมาณใน Chrome และ> 500,000 รายการใน Firefox) คุณสามารถเห็นข้อผิดพลาดนี้เกิดขึ้นในjsperfนี้

เกิดข้อผิดพลาดเนื่องจากเกินขนาดสแต็คการโทรเมื่อเรียกว่า 'Function.prototype.apply' ด้วยอาร์เรย์ขนาดใหญ่เป็นอาร์กิวเมนต์ที่สอง (MDN มีหมายเหตุเกี่ยวกับอันตรายเกินขนาดสแต็คการโทรโดยใช้ Function.prototype.apply - ดูหัวข้อ "ใช้และฟังก์ชั่นในตัว")

สำหรับการเปรียบเทียบความเร็วกับคำตอบอื่น ๆ ในหน้านี้ลองอ่าน jsperf นี้ (ขอบคุณ EaterOfCode) การใช้งานแบบวนรอบนั้นคล้ายกับความเร็วในการใช้Array.push.applyงาน แต่มีแนวโน้มที่จะช้ากว่าArray.slice.applyเล็กน้อย

ที่น่าสนใจถ้าอาเรย์ที่คุณต่อท้ายนั้นเบาบางลงforEachวิธีการที่กล่าวมาข้างต้นสามารถใช้ประโยชน์จากความเบาบางและมีประสิทธิภาพสูงกว่า.applyวิธีที่อิง ตรวจสอบjsperf นี้หากคุณต้องการทดสอบด้วยตัวเอง

ยังไงก็ตามอย่าเพิ่งถูกล่อลวง (เหมือนอย่างที่ฉันเป็น!)

Array.prototype.extend = function (array) {
    array.forEach(this.push, this);
}

เพราะสิ่งนี้สร้างผลลัพธ์ขยะ! ทำไม? เนื่องจากArray.prototype.forEachมีอาร์กิวเมนต์สามตัวสำหรับฟังก์ชันที่เรียกใช้นั่นคือ: (element_value, element_index, source_array) สิ่งเหล่านี้จะถูกส่งไปยังอาร์เรย์แรกของคุณสำหรับการวนซ้ำทุกครั้งforEachหากคุณใช้ "forEach (this.push, this)"!


1
ps เพื่อทดสอบว่า other_array เป็นอาร์เรย์จริงหรือไม่ให้เลือกหนึ่งในตัวเลือกที่อธิบายไว้ที่นี่: stackoverflow.com/questions/767486/…
jcdude

6
คำตอบที่ดี. ฉันไม่ได้ตระหนักถึงปัญหานี้ ฉันอ้างคำตอบของคุณที่นี่: stackoverflow.com/a/4156156/96100
Tim Down

2
.push.applyเป็นจริงเร็วกว่า.forEachใน v8 เร็วที่สุดยังคงเป็นวงอินไลน์
Benjamin Gruenbaum

1
@BenjaminGruenbaum - คุณสามารถโพสต์ลิงก์ไปยังผลลัพธ์บางรายการที่แสดงว่า เท่าที่ฉันเห็นจากผลลัพธ์ที่รวบรวมที่ jsperf ที่เชื่อมโยงในตอนท้ายของความคิดเห็นนี้การใช้.forEachเร็วกว่า.push.applyใน Chrome / Chromium (ในทุกรุ่นตั้งแต่ v25) ฉันไม่สามารถทดสอบการแยก v8 ได้ แต่ถ้าคุณมีโปรดเชื่อมโยงผลลัพธ์ของคุณ ดู jsperf: jsperf.com/array-extending-push-vs-concat/5
jcdude

1
@jcdude jsperf ของคุณไม่ถูกต้อง เช่นเดียวกับองค์ประกอบทั้งหมดในอาร์เรย์ของคุณundefinedดังนั้น.forEachจะข้ามมันทำให้เร็วที่สุด .spliceจริง ๆ แล้วเร็วที่สุด! jsperf.com/array-extending-push-vs-concat/18
EaterOfCode

152

ฉันรู้สึกหรูหราที่สุดในวันนี้คือ:

arr1.push(...arr2);

บทความ MDN ในผู้ประกอบการแพร่กระจายกล่าวถึงวิธีนี้หวานมีความสุขใน ES2015 (ES6):

การผลักดันที่ดีกว่า

ตัวอย่าง: การกดมักจะใช้เพื่อผลักอาร์เรย์ไปยังจุดสิ้นสุดของอาร์เรย์ที่มีอยู่ ใน ES5 นี้มักจะทำดังนี้:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
Array.prototype.push.apply(arr1, arr2);

ใน ES6 ที่มีการแพร่กระจายนี้จะกลายเป็น:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

โปรดทราบว่าarr2ไม่ควรมีขนาดใหญ่มาก (เก็บไว้ที่ประมาณ 100,000 รายการ) เนื่องจาก call stack ล้นออกไปตามคำตอบของ jcdude


1
แค่คำเตือนจากความผิดพลาดที่ฉันทำ รุ่น ES6 arr1.push(arr2)อยู่ใกล้กับ นี่อาจเป็นปัญหาได้ดังนั้นarr1 = []; arr2=['a', 'b', 'd']; arr1.push(arr2)ผลลัพธ์จะเป็นอาร์เรย์ของอาร์เรย์arr1 == [['a','b','d']]แทนที่จะรวมสองอาร์เรย์ มันเป็นความผิดพลาดง่าย ๆ ที่จะทำ ฉันชอบคำตอบที่สองของคุณด้านล่างด้วยเหตุผลนี้ stackoverflow.com/a/31521404/4808079
Seph Reed

มีความสะดวกสบายเมื่อใช้.concatคืออาร์กิวเมนต์ที่สองจะต้องไม่เป็นอาร์เรย์ สิ่งนี้สามารถทำได้โดยการรวมตัวดำเนินการconcatarr1.push(...[].concat(arrayOrSingleItem))
เปรดเข้า

นี่คือ Javascript ที่หรูหราและทันสมัยสำหรับกรณีที่อาร์เรย์เป้าหมายไม่ว่างเปล่า
timbo

เร็วพอหรือไม่
Roel

@RoelDelosReyes: ใช่
odinho - Velmont

46

เป็นคำแรกที่พูดถึงapply()ใน JavaScript เพื่อช่วยให้เข้าใจว่าทำไมเราจึงใช้:

apply()วิธีการเรียกฟังก์ชั่นที่มีการกำหนดthisค่าและการขัดแย้งให้เป็นอาร์เรย์

พุชคาดว่ารายการของรายการที่จะเพิ่มไปยังอาร์เรย์ อย่างไรก็ตามapply()วิธีการใช้อาร์กิวเมนต์ที่คาดหวังสำหรับการเรียกใช้ฟังก์ชันเป็นอาร์เรย์ สิ่งนี้ทำให้เราสามารถอิลีเมนต์pushของอาเรย์หนึ่งไปยังอาเรย์อีกอันได้อย่างง่ายดายด้วยpush()เมธอดbuiltin

ลองนึกภาพคุณมีอาร์เรย์เหล่านี้:

var a = [1, 2, 3, 4];
var b = [5, 6, 7];

และทำอย่างนี้:

Array.prototype.push.apply(a, b);

ผลลัพธ์จะเป็น:

a = [1, 2, 3, 4, 5, 6, 7];

สิ่งเดียวกันสามารถทำได้ใน ES6 โดยใช้ตัวดำเนินการสเปรด (" ...") เช่นนี้:

a.push(...b); //a = [1, 2, 3, 4, 5, 6, 7]; 

สั้นกว่าและดีกว่า แต่ไม่รองรับเบราว์เซอร์ทั้งหมดในขณะนี้

นอกจากนี้หากคุณต้องการย้ายทุกอย่างจากอาเรย์bไปยังการaเทbในกระบวนการคุณสามารถทำได้:

while(b.length) {
  a.push(b.shift());
} 

และผลลัพธ์จะเป็นดังนี้:

a = [1, 2, 3, 4, 5, 6, 7];
b = [];

1
หรือwhile (b.length) { a.push(b.shift()); }ใช่มั้ย
LarsW

37

หากคุณต้องการใช้ jQuery มี$ .merge ()

ตัวอย่าง:

a = [1, 2];
b = [3, 4, 5];
$.merge(a,b);

ผลลัพธ์: a = [1, 2, 3, 4, 5]


1
ฉันจะค้นหาการนำไปใช้ (ในซอร์สโค้ด) ได้jQuery.merge()อย่างไร
ma11hew28

ใช้เวลา 10 นาทีกับฉัน - jQuery เป็นโอเพ่นซอร์สและมีการเผยแพร่ซอร์สบน Github ฉันค้นหา "ผสาน" และค้นหาเพิ่มเติมเกี่ยวกับสิ่งที่ดูเหมือนจะเป็นคำจำกัดความของฟังก์ชันผสานในไฟล์ core.js โปรดดูที่: github.com/jquery/jquery/jbery/blob/master/src/core.js#L331
amn

19

ฉันชอบa.push.apply(a, b)วิธีที่อธิบายข้างต้นและถ้าคุณต้องการคุณสามารถสร้างฟังก์ชั่นห้องสมุดแบบนี้ได้ตลอดเวลา:

Array.prototype.append = function(array)
{
    this.push.apply(this, array)
}

และใช้มันแบบนี้

a = [1,2]
b = [3,4]

a.append(b)

6
ไม่ควรใช้วิธี push.apply เนื่องจากอาจทำให้เกิดการล้นสแต็ก (และดังนั้นจึงล้มเหลว) หากอาร์กิวเมนต์ "อาร์เรย์" ของคุณเป็นอาร์เรย์ขนาดใหญ่ (เช่น> ~ 150000 รายการใน Chrome) คุณควรใช้ "array.forEach" - ดูคำตอบของฉัน: stackoverflow.com/a/17368101/1280629
jcdude

12

เป็นไปได้ที่จะใช้splice():

b.unshift(b.length)
b.unshift(a.length)
Array.prototype.splice.apply(a,b) 
b.shift() // Restore b
b.shift() // 

แต่ถึงกระนั้นก็ไม่เร็วกว่าpush.applyอย่างน้อยใน Firefox 3.0


9
ฉันได้พบสิ่งเดียวกันรอยต่อไม่ได้ปรับปรุงประสิทธิภาพในการผลักแต่ละรายการจนกว่าจะมี 10,000 องค์ประกอบอาร์เรย์jsperf.com/splice-vs-push
Drew

1
+1 ขอบคุณสำหรับการเพิ่มสิ่งนี้และการเปรียบเทียบประสิทธิภาพช่วยให้ฉันพยายามทดสอบวิธีนี้
jjrv

1
การใช้ splice.apply หรือ push.apply อาจล้มเหลวได้เนื่องจากการล้นสแต็กถ้าอาร์เรย์ b มีขนาดใหญ่ พวกเขายังช้ากว่าใช้ "สำหรับ" หรือ "forEach" ห่วง - ดู jsPerf นี้: jsperf.com/array-extending-push-vs-concat/5และคำตอบของฉันstackoverflow.com/questions/1374126/...
jcdude

4

วิธีนี้ใช้ได้ผลสำหรับฉัน (ใช้ตัวดำเนินการสเปรดของ ECMAScript 6):

let array = ['my', 'solution', 'works'];
let newArray = [];
let newArray2 = [];
newArray.push(...array); // Adding to same array
newArray2.push([...array]); // Adding as child/leaf/sub-array
console.log(newArray);
console.log(newArray2);


1

คุณสามารถสร้าง polyfill เพื่อขยายได้ตามที่ฉันมีด้านล่าง มันจะเพิ่มไปยังอาร์เรย์ ในสถานที่และกลับมาเองเพื่อให้คุณสามารถเชื่อมโยงวิธีการอื่น ๆ

if (Array.prototype.extend === undefined) {
  Array.prototype.extend = function(other) {
    this.push.apply(this, arguments.length > 1 ? arguments : other);
    return this;
  };
}

function print() {
  document.body.innerHTML += [].map.call(arguments, function(item) {
    return typeof item === 'object' ? JSON.stringify(item) : item;
  }).join(' ') + '\n';
}
document.body.innerHTML = '';

var a = [1, 2, 3];
var b = [4, 5, 6];

print('Concat');
print('(1)', a.concat(b));
print('(2)', a.concat(b));
print('(3)', a.concat(4, 5, 6));

print('\nExtend');
print('(1)', a.extend(b));
print('(2)', a.extend(b));
print('(3)', a.extend(4, 5, 6));
body {
  font-family: monospace;
  white-space: pre;
}


0

การรวมคำตอบ ...

Array.prototype.extend = function(array) {
    if (array.length < 150000) {
        this.push.apply(this, array)
    } else {
        for (var i = 0, len = array.length; i < len; ++i) {
            this.push(array[i]);
        };
    }  
}

9
ไม่ไม่จำเป็นต้องทำเช่นนี้ A สำหรับลูปที่ใช้ forEach นั้นเร็วกว่าการใช้ push.apply และทำงานไม่ว่าความยาวของอาเรย์ที่จะขยายคือเท่าใด ดูคำตอบที่แก้ไขแล้วของฉัน: stackoverflow.com/a/17368101/1280629 ไม่ว่า ในกรณีใดคุณจะรู้ได้อย่างไรว่า 150000 เป็นหมายเลขที่เหมาะสมที่จะใช้กับเบราว์เซอร์ทั้งหมด นี่เป็นเรื่องเหลวไหล
jcdude

ฮ่า ๆ. คำตอบของฉันจำไม่ได้ แต่ดูเหมือนจะเป็นคำสั่งผสมของคนอื่น ๆ ที่พบในเวลา - เช่นสรุป ไม่ต้องกังวล
zCoder

0

อีกวิธีในการผสานมากกว่าสองอาร์เรย์

var a = [1, 2],
    b = [3, 4, 5],
    c = [6, 7];

// Merge the contents of multiple arrays together into the first array
var mergeArrays = function() {
 var i, len = arguments.length;
 if (len > 1) {
  for (i = 1; i < len; i++) {
    arguments[0].push.apply(arguments[0], arguments[i]);
  }
 }
};

จากนั้นโทรและพิมพ์เป็น:

mergeArrays(a, b, c);
console.log(a)

ผลลัพธ์จะเป็น: Array [1, 2, 3, 4, 5, 6, 7]


-1

คำตอบนั้นง่ายมาก

>>> a = [1, 2]
[1, 2]
>>> b = [3, 4, 5]
[3, 4, 5]
>>> SOMETHING HERE
(The following code will combine the two arrays.)

a = a.concat(b);

>>> a
[1, 2, 3, 4, 5]

Concat ทำหน้าที่คล้ายกันมากกับการต่อสตริง JavaScript มันจะกลับมารวมกันของพารามิเตอร์ที่คุณใส่ลงในฟังก์ชั่น concat ในตอนท้ายของอาร์เรย์ที่คุณเรียกใช้ฟังก์ชั่น crux คือคุณต้องกำหนดค่าที่ส่งคืนให้กับตัวแปรหรือสูญเสีย ตัวอย่างเช่น

a.concat(b);  <--- This does absolutely nothing since it is just returning the combined arrays, but it doesn't do anything with it.

2
ตามที่ระบุไว้อย่างชัดเจนในเอกสารสำหรับArray.prototype.concat()MDNสิ่งนี้จะส่งคืนArray ใหม่มันจะไม่ผนวกเข้ากับอาร์เรย์ที่มีอยู่เนื่องจาก OP ได้ถามอย่างชัดเจน
เหี่ยวแห้ง

-2

ใช้Array.extendแทนArray.push> 150,000 รายการ

if (!Array.prototype.extend) {
  Array.prototype.extend = function(arr) {
    if (!Array.isArray(arr)) {
      return this;
    }

    for (let record of arr) {
      this.push(record);
    }

    return this;
  };
}

-6

ง่ายมากไม่นับรวมกับโอเปอเรเตอร์หรือการใช้งานหากเป็นปัญหา

b.map(x => a.push(x));

หลังจากรันการทดสอบประสิทธิภาพแล้วมันช้ามาก แต่ตอบคำถามเกี่ยวกับการไม่สร้างอาร์เรย์ใหม่ Concat นั้นเร็วกว่าอย่างเห็นได้ชัดแม้แต่ jQuery ก็$.merge()อุ้มมัน

https://jsperf.com/merge-arrays19b/1


4
คุณควรใช้.forEachมากกว่า.mapถ้าคุณไม่ได้ใช้ค่าส่งคืน มันบ่งบอกถึงความตั้งใจในรหัสของคุณได้ดีขึ้น
david

@david - สำหรับแต่ละคนนั้นเอง ฉันชอบ synax ของแต่คุณยังสามารถทำ.map b.forEach(function(x) { a.push(x)} )อันที่จริงฉันเพิ่มเข้าไปในการทดสอบ jsperf และมันก็เร็วกว่าแผนที่ ยังช้าสุด
elPastor

3
นี่ไม่ใช่กรณีของการตั้งค่า วิธีการ 'ใช้งาน' เหล่านี้แต่ละวิธีมีความหมายเฉพาะที่เกี่ยวข้อง การโทรมา.mapที่นี่ดูแปลกมาก b.filter(x => a.push(x))มันจะเป็นเช่นโทร มันใช้งานได้ แต่มันสร้างความสับสนให้ผู้อ่านโดยการอ้างถึงบางสิ่งที่เกิดขึ้นเมื่อมันไม่ได้
david

2
@ elPastor มันควรจะคุ้มค่ากับเวลาของคุณเพราะมีคนอื่นเช่นฉันจะนั่งและเกาคอของเขาสงสัยว่าเกิดอะไรขึ้นที่นั่นในรหัสของคุณที่เขามองไม่เห็น ในกรณีทั่วไปส่วนใหญ่มันเป็นความชัดเจนของเจตนาที่สำคัญไม่ใช่เรื่องของประสิทธิภาพ โปรดเคารพเวลาของผู้ที่อ่านรหัสของคุณเพราะอาจเป็นจำนวนมากเมื่อคุณเป็นหนึ่งเดียว ขอบคุณ
Dmytro Y.

1
@ elPastor ฉันรู้ว่าสิ่งที่.map()ทำและนั่นคือปัญหา ความรู้นี้จะทำให้ฉันคิดว่าคุณต้องการอาเรย์ที่เกิดขึ้นไม่เช่นนั้นจะเป็นการดีที่จะใช้.forEach()เพื่อทำให้ผู้อ่านระมัดระวังเกี่ยวกับผลข้างเคียงของฟังก์ชั่นการโทรกลับ การพูดโซลูชันของคุณอย่างเคร่งครัดจะสร้างจำนวนธรรมชาติเพิ่มเติม (ผลลัพธ์ของpush) ในขณะที่คำถามระบุว่า: "โดยไม่ต้องสร้างอาร์เรย์ใหม่"
Dmytro Y.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.