-->

Split single line string into multiline string in

2019-09-18 11:55发布

问题:

I have a .csv file that I'm calling in JavaScript through a p5.js sketch. One of the fields contains sentences that range from 103 char to 328 char. My script calls the data and displays in randomly on the canvas. Because some of the sentences are very long, they aren't fitting on the canvas properly, so I'd like to split them into 2- or 3-line strings.

I've read up on Template Literals and RegExp in the JavaScript documentation, but all of the examples use string variables written out as a variable. So, for example, something like this in the case of my data:

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.`

That Template Literal would print to the canvas as a multiline object. But what I need to do is have JavaScript create a multiline object from the statements array in my data.

I have a constructor and a prototype that format the color, size, x/y placement, and motion of the sentences.

// 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);
}

So I suppose what I'm wondering is whether I need to create a RegExp, like String.split("[\\r\\n]+") and add \r\n into the data, and if so, where would I put it in my script. I tried in in the Statement.display.prototype, but it just seemed to break the whole script as the statements wouldn't load.

EDIT: I am adding this edit with some trepidation, as I got nailed for not producing a Minimal, Complete, Verifiable example, with "minimal" being the part I got nailed on. That said, here is the top part of my code.

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();
    }
  }
}

I've added that only to provide context for the data type I'm trying to split. There seems to be two points at which I could do the split: the statement array created in setup, or the statements array from the constructor. Meaning that if I go into my data file and add \n where I want to split, which is easy enough as there are only 20 statements, how and where is it best to construct a RegExp that will split those lines?

回答1:

I dunno if I understand exactly that you want, but you can use this to get an array from template

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);

Basically I removed all the commas of your example with replace(/,/gi, ""), then split for \n, and finally trim it.



回答2:

I think the other answer overthinks it a bit.

P5.js already has a handy split() function that you should be using. You can read about it in the reference here.

But basically, all you really need to do is change your statement variable into an array instead of a single string value.

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

This code assumes that you've inserted a // into your .csv file wherever you want a line break. You could use any delimiter you want though.

You would then have to modify your display() function to use the statement variable as an array instead of a single value. How you do that is up to you, but the basic syntax would look like this:

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