[求助] 想了一天也没搞定,如何用 js 分割字符? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
iPc666
V2EX    Javascript

[求助] 想了一天也没搞定,如何用 js 分割字符?

  •  
  •   iPc666 2022-02-11 05:54:03 +08:00 3874 次点击
    这是一个创建于 1390 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大牛,请教个问题。有个翻译 api 每次最多 1000 个字,现在有一段文本大约 5000 字,每行在 100 字左右,我想尽可能多的把这 5000 个字用行分割,但尽可能生成少的数组,从而尽可能少的循环请求翻译接口,请问如何实现呢?

    想了一天没想到什么好方法,如何用 JS 实现呢?

     a = `这是第一行 这是第二行 这是第三行 这是第 n 行 ` 

    最终需要生成数组 b

    b =['尽可能多但不超过 1000 个字,不能在每行中断开','同前一项']

    20 条回复    2022-02-11 21:37:26 +08:00
    ktqFDx9m2Bvfq3y4
        1
    ktqFDx9m2Bvfq3y4  
       2022-02-11 06:02:45 +08:00
    如果你 JS 是负责前端,那么这种事情应该在后端处理,同时也方便后端随时切换到其他翻译 API 。
    iPc666
        2
    iPc666  
    OP
       2022-02-11 06:04:36 +08:00
    @Chad0000 我要用 nodejs 处理
    nifury
        3
    nifury  
       2022-02-11 06:12:34 +08:00
    先按行分割,然后把相邻行合并直到没法再加新行(不然就>1000 字)

    不是最优解,但近似吧……又不是算法题,好实现就行
    ktqFDx9m2Bvfq3y4
        4
    ktqFDx9m2Bvfq3y4  
       2022-02-11 06:13:48 +08:00
    @iPc666 #2 我跟 NodeJS 打交道的也就 Angular 了。后端我用 C#,你这个方案应该不麻烦吧,直接按行分成数组,再将数组分组调用,分组的方式为加起来不超过 1000 字。直接一个循环累加字符长度,直到超过 1000 就把之前的打包成一组进行翻译,然后从这里重新累计字符长度。

    如果你还要计算最优解,尽量再减少数组,可能就需要考虑分析每组翻译“浪费”的字符数,甚至可以把数组打乱顺序以达到最少“浪费”,但这样过于折腾,能节省多少费用,以及是否会影响翻译,综合看来我觉得就没必要了。
    iPc666
        5
    iPc666  
    OP
       2022-02-11 06:31:31 +08:00 via Android
    以每行分割成数组后,怎么通过一次循环实现呢?
    musi
        6
    musi  
       2022-02-11 07:06:37 +08:00
    a = `这是第一行
    这是第二行
    这是第三行

    这是第 n 行
    `
    const arr = a.split('\n');
    const texts = [];
    let str = ''
    while(arr.length) {
    const currentText = arr.shift()
    // 限制每段文本的长度不超过 10
    if(str.length + currentText.length <= 10){
    str += currentText
    }else{
    texts.push(str);
    str = currentText
    }
    }
    texts.push(str);
    str = ''
    console.log(texts)


    => ['这是第一行这是第二行', '这是第三行', '这是第 n 行']
    gzlock
        7
    gzlock  
       2022-02-11 07:12:56 +08:00
    不知道对题目理解的对不对
    https://codepen.io/gzlock/pen/dyZWLZB
    gzlock
        8
    gzlock  
       2022-02-11 07:13:51 +08:00
    @musi #6 有一说一,如果没有了换行符提交去翻译的话,翻译结果绝对有问题
    musi
        9
    musi  
       2022-02-11 07:22:28 +08:00
    @gzlock 这得看原文本有没有标点符号吧,如果标点符号用的规范也不见得有多大问题
    musi
        10
    musi  
       2022-02-11 07:23:43 +08:00
    @gzlock #7 如果原文本没有标点符号,那 op 的一行 100 字翻译也有问题,这就直接无解了。
    iPc666
        11
    iPc666  
    OP
       2022-02-11 07:25:26 +08:00
    用这段代码搞定了

    function splitStrIntoArray(str, maxLength) {
    let i;
    let output = [];
    let lineSoFar = "";
    let temp;
    let line = str.split('\n');
    for (i = 0; i < line.length;) {
    temp = addLineOntoLineWrap(lineSoFar, line[i]);
    if (temp.length > maxLength) {
    if (lineSoFar.length === 0) {
    lineSoFar = temp;
    i++;
    }
    output.push(lineSoFar);
    lineSoFar = "";
    } else {
    lineSoFar = temp;
    i++;
    }
    }
    if (lineSoFar.length > 0) {
    output.push(lineSoFar);
    }
    return output;
    }

    function addLineOntoLineWrap(lineWrap, line) {
    if (lineWrap.length !== 0) {
    lineWrap += "\n";
    }
    return lineWrap + line;
    }

    b = splitStrIntoArray(a,1000)

    madao1993
        12
    madao1993  
       2022-02-11 07:33:30 +08:00
    split 分割字符串,for 循环遍历数组元素,数组的 length 属性相加超过 1000 就 i--然后 continue
    这不是最优解,但是很方便
    iPc666
        13
    iPc666  
    OP
       2022-02-11 07:36:18 +08:00
    @gzlock 你的代码有问题,max 给 1000 , 控制台报错 https://codepen.io/youxiaohou/pen/KKymYbQ
    gzlock
        14
    gzlock  
       2022-02-11 07:41:30 +08:00
    @iPc666 #13 报错处是你后加的代码吧,不背锅
    iPc666
        15
    iPc666  
    OP
       2022-02-11 08:24:18 +08:00
    感谢大家,问题已解决。成品效果图 https://www.crxsoso.com/webstore/detail/fdpohaocaechififmbbbbbknoalclacl
    jorneyr
        16
    jorneyr  
       2022-02-11 08:24:24 +08:00
    String.substring(x, 1000),从这个位置向前找最近的一个换行符作为分割位置。
    x 为上一次的分割位置。
    z4none
        17
    z4none  
       2022-02-11 10:11:47 +08:00
    各行可以乱序提交? 这就是个装箱问题.
    mekingname
        18
    mekingname  
       2022-02-11 10:34:29 +08:00
    问题来了,如果有一个词跨行了怎么办?它翻译的时候肯定会出问题吧。
    RickyC
        19
    RickyC  
       2022-02-11 13:50:18 +08:00
    这是智力题吗?
    一段文字,翻译完不就行了。
    干嘛追求解题效率最高呢?
    iPc666
        20
    iPc666  
    OP
       2022-02-11 21:37:26 +08:00
    跨行了就是人工智能的范畴了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     975 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 22:37 PVG 06:37 LAX 14:37 JFK 17:37
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86