Javascript 与Python';s压缩函数
是否有与Python的zip函数等价的javascript?也就是说,给定多个长度相等的数组,将创建一个对数组 例如,如果我有三个如下所示的数组:Javascript 与Python';s压缩函数,javascript,python,functional-programming,transpose,Javascript,Python,Functional Programming,Transpose,是否有与Python的zip函数等价的javascript?也就是说,给定多个长度相等的数组,将创建一个对数组 例如,如果我有三个如下所示的数组: var array1 = [1, 2, 3]; var array2 = ['a','b','c']; var array3 = [4, 5, 6]; 输出数组应为: var output array:[[1,'a',4], [2,'b',5], [3,'c',6]] 不是Javascript本身内置的。一些常见的Javascript框架(如Pr
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];
输出数组应为:
var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]
不是Javascript本身内置的。一些常见的Javascript框架(如Prototype)提供了一个实现,或者您可以编写自己的实现。该库提供了此函数和许多其他类似Python的函数。Mochikit的开发人员也是Python迷,因此它具有Python的一般风格,并且将异步调用封装在一个类似twisted的框架中。我在纯JS中运行了一下,想知道上面发布的插件是如何完成这项工作的。这是我的结果。我会先说,我不知道这在IE之类的东西中会有多稳定。这只是一个快速的模型
init();
函数init(){
VarOne=[0,1,2,3];
VarTwo=[4,5,6,7];
变量三=[8,9,10,11,12];
var-four=zip(一,二,一);
//返回数组
//四=拉链(一,二,三);
//返回false,因为three.length!==two.length
控制台日志(四个);
}
函数zip(){
for(var i=0;i=1){
if(参数[i].length!==参数[i-1].length){
返回false;
}
}
}
var压缩=[];
对于(var j=0;j<参数[0]。长度;j++){
var toBeZipped=[];
for(var k=0;k
查看库
下划线提供了100多个函数,支持您最喜欢的日常功能助手:映射、筛选、调用,以及更专业的功能:函数绑定、javascript模板、创建快速索引、深度平等性测试等等
–说是谁做的
我最近开始专门为这个功能使用它,它给我留下了很好的第一印象。我正在使用jQuery和CoffeeScript,它与它们非常配合。下划线从他们离开的地方开始,到目前为止还没有让我失望。哦,顺便说一下,它只缩小了3kb
请查看:
_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
// returns [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
2016年更新:
_tarrin = [0..constructor, function(){}, false, undefined, '', 100, 123.324,
2343243243242343242354365476453654625345345, 'sdf23423dsfsdf',
'sdf2324.234dfs','234,234fsf','100,100','100.100']
_parseInt = function(i){return parseInt(i);}
_tarrout = _tarrin.map(_parseInt)
_tarrin.map(function(e,i,a){return [e, _tarrout[i]]})
//'('+_tarrin.map(function(e,i,a){return [e, _tarrout[i]]}).join('),\n(')+')'
>>
(function Number() { [native code] },NaN),
(function (){},NaN),
(false,NaN),
(,NaN),
(,NaN),
(100,100),
(123.324,123),
(2.3432432432423434e+42,2),
(sdf23423dsfsdf,NaN),
(sdf2324.234dfs,NaN),
(234,234fsf,234),
(100,100,100),
(100.100,100)
function * zip(arr1, arr2, i = 0) {
while(arr1[i] || arr2[i]) yield [arr1[i], arr2[i++]].filter(x => !!x);
}
[ ...zip(arr1, arr2) ] // result
这是一个更时髦的Ecmascript 6版本:
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
插图相当于Python{zip(*args)
}:
(FizzyTea指出ES6具有可变参数语法,因此下面的函数定义将类似于python,但请参见下面的免责声明…这将不是它自己的逆函数,因此zip(zip(x))
将不等于x
;尽管Matt Kramer指出zip(…zip(…x))==x
(就像普通python中的zip(*zip(*x))==x
)
相当于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
(请注意,…
语法此时可能会有性能问题,将来也可能会有性能问题,因此,如果使用带有可变参数的第二个答案,可能需要对其进行性能测试。)
这里有一条单行线:
函数zip(数组){
返回数组[0]。映射(函数(\uI){
返回数组.map(函数(数组){returnarray[i]})
});
}
//>拉链([[1,2],[11,22],[111222]]
// [[1,11,111],[2,22,222]]]
//如果您认为以下是有效的返回值:
//>zip([])
// []
//然后你可以特例,也可以直接做
//返回数组。长度==0?[]:数组[0]。映射(…)
上面假设数组的大小应该是相同的。它还假设您传入一个列表参数列表,这与Python版本中参数列表是可变的不同。如果您想要所有这些“功能”,请参见下面。只需要大约2行额外的代码 下面将模拟Python在数组大小不相等的边缘情况下的
zip
行为,默默地假装数组的较长部分不存在:
函数zip(){
var args=[].slice.call(参数);
var shortest=args.length==0?[]:args.reduce(函数(a,b){
返回长度为.zip的文件([1,2],[11,22],[111222333])
// [[1,11,111],[2,22,222]]]
//>zip()
// []
这将模拟Python的itertools.zip\u longest
行为,在未定义数组的位置插入undefined
:
函数zip(){
var args=[].slice.call(参数);
var longest=args.reduce(函数(a,b){
返回a.length>b.length?a:b
}, []);
返回最长的.map(函数(\uI){
return args.map(函数(数组){return array[i]})
});
}
//>拉链([1,2],[11,22],[111222333])
//[1,11111],[2,22222],[null,null,333]]
//>zip()
// []
如果您使用最后两个版本(变量又称多参数版本),那么zip就不再是它自己的反义词。要模仿Python中的zip(*[…])
习惯用法,当您想要反转zip函数或者如果您想要类似地拥有可变数量的列表作为输入时,您需要执行zip.apply(this,[…])
附录: 要使此句柄可用于任何iterable(例如,在Python中,可以对字符串、范围、映射对象等使用
zip
),可以定义以下内容:
功能iterView(iterable){
//返回与iterable相等的数组
}
但是,如果您在以下内容中编写zip
,则即使这样也没有必要:
函数zip(数组){
返回Array.apply(null,数组(数组[0].length)).map(函数(\ui){
返回数组.map(函数(数组){returnarray[i]})
});
}
演示:
(或者,如果您已经编写了Python风格的函数,您可以使用range(…)
Python风格的函数。最终您将成为
//Arrays: aIn, aOut
Array.prototype.map.call( aIn, function(e,i){return [e, aOut[i]];})
_tarrin = [0..constructor, function(){}, false, undefined, '', 100, 123.324,
2343243243242343242354365476453654625345345, 'sdf23423dsfsdf',
'sdf2324.234dfs','234,234fsf','100,100','100.100']
_parseInt = function(i){return parseInt(i);}
_tarrout = _tarrin.map(_parseInt)
_tarrin.map(function(e,i,a){return [e, _tarrout[i]]})
//'('+_tarrin.map(function(e,i,a){return [e, _tarrout[i]]}).join('),\n(')+')'
>>
(function Number() { [native code] },NaN),
(function (){},NaN),
(false,NaN),
(,NaN),
(,NaN),
(100,100),
(123.324,123),
(2.3432432432423434e+42,2),
(sdf23423dsfsdf,NaN),
(sdf2324.234dfs,NaN),
(234,234fsf,234),
(100,100,100),
(100.100,100)
const zip = (...arrays) => {
const length = Math.min(...arrays.map(arr => arr.length));
return Array.from({ length }, (value, index) => arrays.map((array => array[index])));
};
console.log(zip(
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[11, 221]
));
console.log(zip(
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111, 212, 323, 433, '1111']
));
console.log(zip(
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
const zipLongest = (placeholder = undefined, ...arrays) => {
const length = Math.max(...arrays.map(arr => arr.length));
return Array.from(
{ length }, (value, index) => arrays.map(
array => array.length - 1 >= index ? array[index] : placeholder
)
);
};
console.log(zipLongest(
undefined,
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
console.log(zipLongest(
null,
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
console.log(zipLongest(
'Is None',
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
function *zip (...iterables){
let iterators = iterables.map(i => i[Symbol.iterator]() )
while (true) {
let results = iterators.map(iter => iter.next() )
if (results.some(res => res.done) ) return
else yield results.map(res => res.value )
}
}
function* zip(...toZip) {
const iterators = toZip.map((arg) => arg[Symbol.iterator]());
const next = () => toZip = iterators.map((iter) => iter.next());
while (next().every((item) => !item.done)) {
yield toZip.map((item) => item.value);
}
}
import {zip, zipLongest} from 'pythonic';
const arr1 = ['a', 'b'];
const arr2 = ['c', 'd', 'e'];
for (const [first, second] of zip(arr1, arr2))
console.log(`first: ${first}, second: ${second}`);
// first: a, second: c
// first: b, second: d
for (const [first, second] of zipLongest(arr1, arr2))
console.log(`first: ${first}, second: ${second}`);
// first: a, second: c
// first: b, second: d
// first: undefined, second: e
// unzip
const [arrayFirst, arraySecond] = [...zip(...zip(arr1, arr2))];
const zip = (arr,...arrs) =>(
arr.map(
(v,i) => arrs.reduce((a,arr)=>[...a, arr[i]], [v])))
function * zip(arr1, arr2, i = 0) {
while(arr1[i] || arr2[i]) yield [arr1[i], arr2[i++]].filter(x => !!x);
}
[ ...zip(arr1, arr2) ] // result
function zip(zipper, ...arrays) {
if (zipper instanceof Array) {
arrays.unshift(zipper)
zipper = (...elements) => elements
}
const length = Math.min(...arrays.map(array => array.length))
const zipped = []
for (let i = 0; i < length; i++) {
zipped.push(zipper(...arrays.map(array => array[i])))
}
return zipped
}