JS实现古诗竖排从右至左

一个老题目,将下面古诗文由横排,变成古文竖排模式:

静夜思 李白
床前明月光,
疑似地上霜。
举头望明月,
低头思故乡。

变成:

低|举|疑|床|静
头|头|似|前|夜
思|望|地|明|思
故|明|上|月| 
乡|月|霜|光|李
。|,|。|,|白

1.原始文本转成二维数组,简化起见,暂时去掉标点符号和标题作者:

console.log(
	"床前明月光\n疑似地上霜\n举头望明月\n低头思故乡".split(/\n/).map( v => v.split(''))
);

输出:

[
  [ '床', '前', '明', '月', '光' ],
  [ '疑', '似', '地', '上', '霜' ],
  [ '举', '头', '望', '明', '月' ],
  [ '低', '头', '思', '故', '乡' ]
]

直接一行行输出的时候,就是横排输出,变成竖排,刚好是行列互换,在二维数组、矩阵中,就是矩阵转置transpose,4x5的矩阵行列互换后,变成5x4,现在要实现一个transpose函数:

let arr = [
    [1, 2, 3],
    [4, 5, 6]
];
// 取首行,循环每一列,循环列的时候,取对应列的元素变成行返回,如果某行元素不足首行,可以填充空白字符
console.log( 
	arr[0].map((_, col) =>
	    arr.map(row => row[col])
	)
);

转换后变成:

[ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]

封装成一个函数:

// tranpose函数实现有很多种,这是最简单一种
let transpose = arr => {
	return arr[0].map((_, col) =>
	    arr.map(row => row[col])
	);
};
console.log( 
	transpose("床前明月光\n疑似地上霜\n举头望明月\n低头思故乡".split(/\n/).map( v => v.split('')))
);

输出:

[
  [ '床', '疑', '举', '低' ],
  [ '前', '似', '头', '头' ],
  [ '明', '地', '望', '思' ],
  [ '月', '上', '明', '故' ],
  [ '光', '霜', '月', '乡' ]
]

变成字符串输出:

let transpose = arr => {
	return arr[0].map((_, col) =>
	    arr.map(row => row[col])
	);
};
console.log( 
	transpose("床前明月光\n疑似地上霜\n举头望明月\n低头思故乡".split(/\n/).map( v => v.split('')))
	.map( row => row.join("|") )
	.join("\n")
);

输出:

|||低
前|||头
明|||思
月|||故
光|||

现在是从左到右,要变成从右向左,每一行还需要先反转数组:row.reverse()

let transpose = arr => {
	return arr[0].map((_, col) =>
	    arr.map(row => row[col])
	);
};
let str = transpose("床前明月光\n疑似地上霜\n举头望明月\n低头思故乡".split(/\n/).map( v => v.split('')))
.map( row => row.reverse().join("|") )
.join("\n");
console.log(str);

输出:

低|举|疑|床
头|头|似|前
思|望|地|明
故|明|上|月
乡|月|霜|光

如果不想定义函数,可以用reduce来实现:

console.log(
	[
	    [1, 2, 3],
	    [4, 5, 6]
	].reduce((s, a) => (a.map((v, j)=> s[j] = (s[j] || []).concat([v])), s), [])
);

输出:

[ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]

reduce改写:

let str = '静夜思 李白\n床前明月光,\n疑似地上霜。\n举头望明月,\n低头思故乡。'.split(/\n/)
.map( v => v.split('') )
.reduce((s, a) => (a.map((v, j)=> s[j] = (s[j] || []).concat([v])), s), [])
.map( d => d.reverse().join('|') )
.join('\n');
console.log(str);

输出:

低|举|疑|床|静
头|头|似|前|夜
思|望|地|明|思
故|明|上|月| 
乡|月|霜|光|李
。|,|。|,|白

ruby内置了transpose函数:

# puts "静夜思 李白\n床前明月光,\n疑似地上霜。\n举头望明月,\n低头思故乡。".split(/\n/).map(&:chars).transpose.map{ it.reverse * '|' } * "\n"
# csdn的 ruby 版本过低,上面代码不能正常运行
puts "静夜思 李白\n床前明月光,\n疑似地上霜。\n举头望明月,\n低头思故乡。".split(/\n/).map(&:chars).transpose.map{|it| it.reverse.join('|') }.join("\n")

输出:

低|举|疑|床|静
头|头|似|前|夜
思|望|地|明|思
故|明|上|月| 
乡|月|霜|光|李
。|,|。|,|白

完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值