【问题标题】:Split single line string into multiline string in JavaScript/p5.js在 JavaScript/p5.js 中将单行字符串拆分为多行字符串
【发布时间】:2016-06-11 11:57:58
【问题描述】:

我有一个 .csv 文件,我通过 p5.js 草图在 JavaScript 中调用它。其中一个字段包含范围从 103 字符到 328 字符的句子。我的脚本调用数据并随机显示在画布上。因为有些句子很长,在画布上不合适,所以我想把它们分成 2 行或 3 行的字符串。

我已经阅读了 JavaScript 文档中的 Template LiteralsRegExp,但所有示例都使用写成变量的字符串变量。因此,例如,在我的数据中是这样的:

var myString = `We can lift up people and places who've been left out, 
        from our inner cities to Appalachia,  
        in every manufacturing town hollowed out when the factory closed, 
        every community scarred by substance abuse, 
        every home where a child goes to bed hungry.`

Template Literal 将作为多行对象打印到画布上。但我需要做的是让 JavaScript 从我的数据中的 statements 数组创建一个多行对象。

我有一个constructor 和一个prototype 来格式化句子的颜色、大小、x/y 位置和运动。

// Function to align statements, categories, and polarity
function Statement(category, polarity, statement) {
  this.category = category;
  this.statement = statement;
  this.polarity = polarity;
  this.x = random(width/2);
  this.y = random(height);
  this.dx = random(-speed, speed);
  this.dy = random(-speed, speed);
}
// Attach pseudo-class methods to prototype;
// Maps polarity to color and x,y to random placement on canvas
Statement.prototype.display = function() {
  this.x += this.dx;
  this.y += this.dy;
  if(this.x > width+10){
    this.x = -10
  }
  if(this.y > height+10) {
    this.y = -10
  }
  if(this.polarity == -1){
    fill(205, 38, 38);
  }
  else if(this.polarity == 1){
    fill(0, 145, 205);
  }
  else{
    fill(148, 0, 211);
  }
  textSize(14);
  text(this.statement, this.x, this.y);
}

所以我想我想知道我是否需要创建一个RegExp,例如String.split("[\\r\\n]+") 并将\r\n 添加到数据中,如果需要,我会将它放在我的脚本中的什么位置。我在Statement.display.prototype 中尝试过,但它似乎破坏了整个脚本,因为语句无法加载。

编辑:我有些不安地添加了这个编辑,因为我因为没有生成 Minimal, Complete, Verifiable 示例而被钉牢,而“最小”是我被钉牢的部分。也就是说,这是我的代码的顶部。

var clContext;
var speed = 0.8;
var statements = [];
var category = [];
var canvas;



      //load the table of Clinton's words and frequencies
function preload() {
        clContext = loadTable("cl_context_rev.csv", "header");
      }

function setup() {
  canvas = createCanvas(680, 420);
  canvas.mousePressed(inWidth);
  background(51);
  // Calling noStroke once here to avoid unecessary repeated function calls
  noStroke();
  // iterate over the table rows
  for (var i = 0; i < clContext.getRowCount(); i++) {
    var category = clContext.get(i, "category");
    var statement = clContext.get(i, "statement");
    var polarity = clContext.get(i, "polarity");
    statements[i] = new Statement(category, polarity, statement);
  }
}

function draw() {
  if (mouseIsPressed) {
    background(51);
    for (var i = 0; i < statements.length; i++) {
      statements[i].display();
    }
  }
}

我添加它只是为了为我尝试拆分的数据类型提供上下文。似乎有两点我可以进行拆分:在设置中创建的statement 数组,或者来自构造函数的statements 数组。这意味着如果我进入我的数据文件并在我想要拆分的位置添加\n,这很容易,因为只有 20 条语句,那么最好如何以及在哪里构造一个可以拆分这些行的RegExp

【问题讨论】:

  • 您可以通过定义最大长度,然后通过在长度限制内的最后一个单词的末尾将其拆分为数组项来减少字符串。我在这个答案中做了类似的工作stackoverflow.com/questions/37361878/…
  • 谢谢@Redu,但不幸的是,他也没有这样做。我尝试使用我的 var 名称对其进行调整,每次尝试使用各种配置运行它时,我都会收到 statement.split is not a function 错误。我不确定,但这可能是 p5.js 的问题。我曾尝试过其他 split 方法,我遇到过并且总是遇到该错误。我将尝试在 p5.js 的 GitHub 存储库中创建一个 issue,但它们并不是最快的响应者。
  • statement.split is not a function 是一个 TypeError 并且意味着语句根本不是字符串类型。你检查过typeof statement吗?
  • 是的,@Redu,我查过了,它是字符串类型的。
  • 这很不寻常。当您在应用程序中喜欢 console.log(String.prototype.split()) 时,您是否看到 function split() { [native code] }..?

标签: javascript regex string p5.js template-literals


【解决方案1】:

我不知道我是否完全理解您想要的,但您可以使用它从模板中获取数组

var myString = `We can lift up people and places who've been left out, 
        from our inner cities to Appalachia,  
        in every manufacturing town hollowed out when the factory closed, 
        every community scarred by substance abuse, 
        every home where a child goes to bed hungry.`
        
var array = myString.replace(/,/gi, "").split("\n").map(x => x.trim());

console.log(array);

基本上我用replace(/,/gi, "")删除了你示例的所有逗号,然后拆分为\n,最后修剪它。

【讨论】:

  • 谢谢@AralRoca,但并不完全正确。我的语句在数据文件的行中,变量名为statement。我已将这些语句调用到setup() 中的一个数组中。此外,当我使用您的代码的修改版本时:var array = statements.split("\n").map(x =&gt; x.trim());,我得到了Uncaught TypeError: statements.split is not a function。也许我应该放更多我的脚本,我可以这样做,但我在上一个问题中因为没有制作MINIMAL, Complete, and Verifiable example 而被钉住,至少是我被钉住的具体问题。
  • 因为split原型只适用于strings。如果你有带有语句变量的语句,也许你可以试试这个:const templateToArray = (s) =&gt; s.replace(/,/gi, "").split("\n").map(x =&gt; x.trim()); 然后:const array = statements.map( s =&gt; templateToArray(s.statement)); 最后你可以展平,例如,使用 lodash:const flattenArray = _.flattenDeep(array);
  • 感谢@AralRoca,但我认为因为const 是在任何函数之前声明的,所以它不起作用。第二个const 引发cannot map to undeclared 错误。我的statement 变量实际上是在setup() 中声明的,因为我必须首先使用preload = loadTable() 来引入数据。您的示例基于我输入以引用模板文字的虚拟变量。这实际上不是我的数据的样子,它只是 .csv 文件中的大量句子行。您可以在我的代码顶部的 Edit: 中看到所有这些内容。
  • 嗯,你需要先声明变量statementshehe。对不起,因为我认为我最终不明白你想要的
  • .@AralRoca 变量 var statements = [] 声明在我的脚本的最顶部(他),但它没有包含在我的帖子中,因为我一直因为发布太多而受到打击我的剧本或不够!我知道最小的、完整的、可验证的例子,但试图让每个人都满意是很荒谬的,因为每个人似乎对这意味着什么有不同的想法,而且他们都让我知道我是如何失败的!
【解决方案2】:

我认为另一个答案有点想多了。

P5.js 已经有一个方便的split() 函数,您应该使用它。您可以在参考文献here 中了解它。

但基本上,您真正需要做的就是将您的 statement 变量更改为数组而不是单个字符串值。

function Statement(category, polarity, statement) {
  this.statement = split(statement, "//");
  //rest of your code

此代码假定您已将// 插入到您的.csv 文件中您想要换行的任何位置。你可以使用任何你想要的分隔符。

然后您必须修改您的display() 函数以将statement 变量用作数组而不是单个值。如何做到这一点取决于您,但基本语法如下所示:

text(this.statement[0], this.x, this.y);
text(this.statement[1], this.x, this.y+25);

【讨论】:

  • 很奇怪。曾尝试使用 p5 的splitTokens() 进行类似的操作,但没有成功,但确实如此。通过display() 函数,我假设您的意思是Statement.prototype.display = function(),因为那是我拥有text(this.statement, this.x, this.y) 的地方。这给我留下了一个问题。显然,我还必须在setup() 下更改statements[i] = new Statement(polarity, statement);,在draw() 下更改for (var i = 0; i &lt; statements.length; i++) { statements[i].display();},因为我收到Cannot read property 'display' of undefined 错误。但是statements[i] 不应该涵盖所有实例吗?
  • @LesleyLathrop 在 cmets 中谈论代码真的很难,而且 cmets 并不是真正为扩展讨论而设计的。我建议用你更新的代码(最好是minimal reproducible example)和你的新问题创建一个新帖子,我们将从那里开始。
  • 我在上面添加了另一个编辑,其中包含大部分完整的修改代码。我不会发布一个新问题,也不会有人因为我重复了一个已经被问过的问题而敲我。而且,顺便说一句,您不再需要提醒我有关最小、完整、可验证的示例。我明白了,尽管作为一名作家,我不得不说“最小”和“完整”是矛盾的术语。当我没有发布足够的代码时,我会被钉死,而你会因为发布太多代码而钉死我。
  • @LesleyLathrop 我没有提醒你任何事情。 StackOverflow 自动将[mcve] 扩展为minimal reproducible example,所以它是自动发生的。我不确定您为什么会如此敌视,但如果您将后续问题发布到自己的帖子中,我将很乐意提供帮助。如果我们继续编辑我们的问题和答案,这会让后来的读者感到非常困惑。如果你不想那样做,没关系,但我会祝你好运并继续前进。我可以回答很多问题,而不会被我试图帮助的人大喊大叫。
  • .@KevinWorkman,我绝对没有对你或任何人大喊大叫,我的评论中没有敌意。我只是表示沮丧,无论我发布多少代码或多少代码,总会有人对此提出异议并告诉我发布minimal reproducible example。如果你认为我对你有任何敌意,我深表歉意,因为我不是。根据您的要求,我有posted a new question,非常感谢您提供的任何帮助。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 2021-11-17
相关资源
最近更新 更多