อัพเดท 2016:
ต่อไปนี้เป็นรุ่น Snazzier Ecmascript 6:
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
ภาพประกอบ ถึงPython { zip(*args)
}:
> zip([['row0col0', 'row0col1', 'row0col2'],
['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
["row0col1","row1col1"],
["row0col2","row1col2"]]
(และ FizzyTea ชี้ให้เห็นว่า ES6 มีไวยากรณ์อาร์กิวเมนต์ variadic ดังนั้นนิยามฟังก์ชันต่อไปนี้จะทำหน้าที่เหมือนงูหลาม แต่ดูด้านล่างสำหรับข้อจำกัดความรับผิดชอบ ... นี้จะไม่เป็นสิ่งที่ตรงกันข้ามของตัวเองดังนั้นzip(zip(x))
จะไม่เท่ากันx
; แม้ในขณะที่แมตต์เครเมอชี้ให้เห็นzip(...zip(...x))==x
(เช่น ในงูหลามปกติzip(*zip(*x))==x
))
ทางเลือกคำนิยาม equiv ถึงPython { zip
}:
> zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]))
> zip( ['row0col0', 'row0col1', 'row0col2'] ,
['row1col0', 'row1col1', 'row1col2'] );
// note zip(row0,row1), not zip(matrix)
same answer as above
(โปรดทราบว่า...
ไวยากรณ์อาจมีปัญหาด้านประสิทธิภาพในเวลานี้และอาจเป็นไปได้ในอนาคตดังนั้นหากคุณใช้คำตอบที่สองพร้อมกับข้อโต้แย้งหลากหลายคุณอาจต้องการทดสอบมัน)
นี่คือผู้เผยแพร่:
function zip(arrays) {
return arrays[0].map(function(_,i){
return arrays.map(function(array){return array[i]})
});
}
// > zip([[1,2],[11,22],[111,222]])
// [[1,11,111],[2,22,222]]]
// If you believe the following is a valid return value:
// > zip([])
// []
// then you can special-case it, or just do
// return arrays.length==0 ? [] : arrays[0].map(...)
ด้านบนจะถือว่าอาร์เรย์มีขนาดเท่ากันเท่าที่ควร นอกจากนี้ยังถือว่าคุณผ่านรายการอาร์กิวเมนต์รายการเดียวซึ่งแตกต่างจากรุ่น Python ที่รายการอาร์กิวเมนต์เป็น Variadic หากคุณต้องการ "คุณสมบัติ" ทั้งหมดเหล่านี้ดูด้านล่าง ใช้รหัสพิเศษอีกประมาณ 2 บรรทัด
ต่อไปนี้จะเลียนแบบzip
พฤติกรรมของงูหลามในกรณีขอบซึ่งอาร์เรย์มีขนาดไม่เท่ากันโดยไม่มีการแกล้งทำเป็นส่วนที่ยาวกว่าของอาร์เรย์อย่างเงียบ ๆ :
function zip() {
var args = [].slice.call(arguments);
var shortest = args.length==0 ? [] : args.reduce(function(a,b){
return a.length<b.length ? a : b
});
return shortest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222]]]
// > zip()
// []
สิ่งนี้จะเลียนแบบitertools.zip_longest
พฤติกรรมของไพ ธ อนโดยundefined
ที่ไม่ได้กำหนดอาร์เรย์ไว้:
function zip() {
var args = [].slice.call(arguments);
var longest = args.reduce(function(a,b){
return a.length>b.length ? a : b
}, []);
return longest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222],[null,null,333]]
// > zip()
// []
หากคุณใช้สองเวอร์ชันล่าสุด (ผันแปร aka รุ่นหลายอาร์กิวเมนต์หลายตัว) zip จะไม่ตรงกันข้ามของมันเอง ในการเลียนแบบzip(*[...])
สำนวนจาก Python คุณจะต้องทำzip.apply(this, [...])
เมื่อคุณต้องการสลับฟังก์ชั่น zip หรือถ้าคุณต้องการให้จำนวนรายการที่หลากหลายเป็นอินพุตเหมือนกัน
ภาคผนวก :
เพื่อให้การจัดการนี้ iterable ใด ๆ (เช่นใน Python คุณสามารถใช้zip
กับสตริงช่วงวัตถุแผนที่ ฯลฯ ) คุณสามารถกำหนดต่อไปนี้:
function iterView(iterable) {
// returns an array equivalent to the iterable
}
อย่างไรก็ตามหากคุณเขียนด้วยวิธีzip
ต่อไปนี้แม้จะไม่จำเป็นก็ตาม:
function zip(arrays) {
return Array.apply(null,Array(arrays[0].length)).map(function(_,i){
return arrays.map(function(array){return array[i]})
});
}
การสาธิต:
> JSON.stringify( zip(['abcde',[1,2,3,4,5]]) )
[["a",1],["b",2],["c",3],["d",4],["e",5]]
(หรือคุณสามารถใช้range(...)
ฟังก์ชั่น Python-style ถ้าคุณเขียนไปแล้วในที่สุดคุณจะสามารถใช้ ECMAScript array comprehensions หรือ Generators)