一个老题目,将下面古诗文由横排,变成古文竖排模式:
静夜思 李白
床前明月光,
疑似地上霜。
举头望明月,
低头思故乡。
变成:
低|举|疑|床|静
头|头|似|前|夜
思|望|地|明|思
故|明|上|月|
乡|月|霜|光|李
。|,|。|,|白
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")
输出:
低|举|疑|床|静
头|头|似|前|夜
思|望|地|明|思
故|明|上|月|
乡|月|霜|光|李
。|,|。|,|白
完。