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")
输出:
低|举|疑|床|静
头|头|似|前|夜
思|望|地|明|思
故|明|上|月|
乡|月|霜|光|李
。|,|。|,|白
完。