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 · 3030 次点击
    这是一个创建于 777 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    最终需要生成数组 b

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

    20 条回复    2022-02-11 21:37:26 +08:00
    Chad0000
        1
    Chad0000  
       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 字)

    不是最优解,但近似吧……又不是算法题,好实现就行
    Chad0000
        4
    Chad0000  
       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   ·   我们的愿景   ·   实用小工具   ·   1010 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:15 · PVG 06:15 · LAX 15:15 · JFK 18:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.