Divide the string into several segments according to its position value

Here is a piece of text that I would like to divide into multiple sections, determined by the offset and length.

If you have any questions or comments and would like to get in touch with ABC, please go to our customer support page.

Below is a function that can extract text based on its offset and length.

 let offset = '83';
  let length = '16';   

  getText(offset, length, text: string) {
    return text.substr(offset, length);
  }

When using the function above, it will return the text: customer support.

The main issue

I need to split the text into the sections before and after. For example:

text1: Do you have questions or comments and do you wish to contact ABC? Please visit our

text2: customer support

text3: page

Is it possible to achieve this?

Answer №1

If you're looking to tackle a similar issue, building on the functionality of breakAt can be a good starting point. breakAt essentially splits a string at specified cut points, while a function like intoPairs breaks a list into its contiguous pairs. This can have various practical uses within your application.

Here's an example implementation following this approach:

const intoPairs = xs => xs.slice(1).map((x, i) => [xs[i], x])
const breakAt = (places, str) => intoPairs([0, ...places, str.length]).map(
  ([a, b]) => str.substring(a, b)
)
const getText = (offset, length, str) => breakAt([offset, offset + length], str)

const str = "Do you have questions or comments and do you wish to contact ABC? Please visit our customer support page."
console.log(getText(83, 16, str))

The output format may not be clear, but in this example, an array is generated containing the text before, within, and after the specified offset, length, and str.


Update

In response to a follow-up question regarding breaking out multiple sub-strings, this updated version of the function allows for multiple offset/length pairs to further break down the text. The pairs are sorted to simplify the process, but potential overlaps are left to be handled by the user.

const intoPairs = xs => xs.slice(1).map((x, i) => [xs[i], x])
const breakAt = (places, str) => intoPairs([0, ...places, str.length]).map(
  ([a, b]) => str.substring(a, b)
)
const breakWhere = (words, str) => breakAt(
  words.sort(({ offset: o1 }, { offset: o2 }) => o1 - o2).reduce(
    (a, { offset, length }) => [...a, offset, offset + length],
    []
  ),
  str
)

const str = "Do you have questions or comments and do you wish to contact ABC? Please visit our customer support page."

console.log(breakWhere([
  { offset: 83, length: 16 }, // "customer support"
  { offset: 12, length: 9 }, // "questions"
  { offset: 25, length: 8 }, // "comments"
], str))

The slice call in the function is used to avoid mutation of the list of offset/length pairs. This can be omitted if necessary.

Another Update

Addressing another follow-up question about formatting the output into nodes to differentiate between plain text and links, this version of the function creates nodes based on the data provided. Each node is tagged as either 'text' or 'link', with link nodes containing an additional 'path' property.

const intoPairs = xs => xs.slice(1).map((x, i) => [xs[i], x])
const breakAt = (places, str) => intoPairs([0, ...places, str.length]).map(
  ([a, b]) => str.substring(a, b)
)
const breakWhere = (words, str) => breakAt(
  words.reduce((a, { offset, length }) => [...a, offset, offset + length], []),
  str
)

const createNodes = (links, str) => {
  const sortedLinks = links.slice(0).sort(({ offset: o1 }, { offset: o2 }) => o1 - o2)

  return breakWhere(sortedLinks, str).map((s, i) => i % 2 === 0
    ? { data: s, type: 'text' }
    : { data: s, type: 'link', path: sortedLinks[(i - 1) / 2].path }
  ).filter(({ data }) => data.length > 0)
}

const str = "Do you have questions or comments and do you wish to contact ABC? Please visit our customer support page."

const links = [
  {offset: 83, length: 16, path: '/path/to/custSupport'},
  {offset: 12, length: 9, path: 'path/to/questions'},
  {offset: 25, length: 8, path: 'path/to/comments'},
]

console.log(createNodes(links, str))

This function creates nodes based on the provided links, categorizing them as 'text' or 'link' nodes with an optional 'path' property. The filtering step at the end removes any potentially empty text nodes resulting from the node creation process.

Overall, this approach is designed in a layered manner, building upon helper functions to achieve the desired functionality. While it may not be optimized for performance due to its layered nature, it offers flexibility and adaptability to changing requirements.

Answer №2

If you need to adjust this to remove unnecessary spaces and/or punctuation.

const message = 'Are you looking for answers or feedback and do you need to reach out to XYZ? Feel free to check out our customer service page.'

const start = 83;
const length = 16;

function getMessage(startIndex, characters, message) {
    return { message1: message, message2: message.substr(startIndex, characters), message3: message.substr(startIndex + characters) };
}

const splitMessage = getMessage(start, length, message);
console.log(splitMessage)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Balanced arrangement of components

As I work on my first electron app, I've created the initial layout. My goal is to have elements resize when the user adjusts the window size: The red part should change in both width and height The blue part should only adjust in height, not width ...

Difficulty with Jquery's random selection of grid divs

I am working on a grid layout consisting of 9 divs nested in columns of three. The objective is that when the main grid (with ID #left) is clicked, two divs from the middle row (row="1") should have the class .show randomly applied to them. In the column w ...

Encountered a surprise hiccup while attempting to upload file to AWS S3 using browser (putObject

After successfully obtaining a presigned URL through my Node/Express backend for a putObject request on S3, I attempt to upload the relevant files via the browser. However, when making the put request through the browser (or Postman), I encounter a 400 or ...

Ways to address the CORS problem in an ajax function without relying on json

When I run my ajax function: function fn_nextitem(sliderNo){ $.get("/index.php?op=ajax", {slide_no:sliderNo},function(resp) { if (resp) { $('#Div').append(resp); } else { } } This is how my ph ...

javascript detect when two div elements are overlapping

On my webpage, I have implemented the effect.shrink() function. However, when clicking quickly on the page, the div tags start overlapping with other elements. What is the best way to solve this issue? I am using both scriptaculous.js and prototype.js fo ...

What is the best way to integrate Angular types (excluding JS) into tsconfig to avoid the need for importing them constantly?

Lately, I've been dedicated to finding a solution for incorporating Angular types directly into my .d.ts files without the need to import them elsewhere. Initially, I attempted to install @types/angular, only to realize it was meant for AngularJS, whi ...

What is the best way to completely clear $rootScope when a user signs out of my application?

In my development work, I frequently find myself using $rootScope and $scope within controllers and services. Despite searching through numerous Stack Overflow answers for a solution to clear all $scope and $rootScope values, such as setting $rootScope t ...

Showing the number of times a button has been pressed

I have written some HTML code to create a button and now I am looking for guidance on how I can use Vue.js to track how many times the button has been clicked. Here is what I have so far: <div class="123"> <button id = "Abutton&q ...

Save room for text that shows up on its own

I am currently dealing with a situation where text appears conditionally and when it does, it causes the rest of the page to be pushed down. Does anyone know the best way to reserve the space for this text even when it's not visible so that I can pre ...

Tips for displaying a refresh indicator while making an ajax call for refreshing data:

I have successfully implemented jQuery code that refreshes a specific div every 10 seconds without reloading the entire page. However, during this refresh process, the user does not visually perceive any changes happening in the browser. While there are n ...

Tips for broadcasting a router event

Currently, I am working with 2 modules - one being the sidenav module where I can select menus and the other is the content module which contains a router-outlet. I am looking for the best way to display components in the content module based on menu selec ...

Activate the extended view of a Material-UI Accordion

When using Accordions to display editable entities, we often want to keep modified entities in the expanded state. Currently, we have had to duplicate functionality by lifting up the expanded state into the accordion wrapper to prevent any controlled <- ...

Node.js and Express facing challenge with Stripe checkout functionality

I am encountering an issue while attempting to integrate stripe into my checkout process. When I click on the checkout button, instead of being directed to the checkout page, I receive the following message: {"url":"https://checkout.stripe.c ...

Is there a way to transmit a value from a page item on the client side to the server side in Oracle Apex without needing to submit the form?

I implemented a JavaScript function to capture the unique ROWIDs of selected rows in the GRID and send them to a specific page item. var gridView = apex.region("emp").call("getCurrentView"), selectedRecords = gridView.getSelectedRec ...

Implementing user authentication in Rails with Devise and Backbone framework

I am just getting started with backbone.js. Currently, I am working on a rails application utilizing the "backbone-on-rails" gem. After successfully incorporating 3 models and rendering views with backbone, now I am looking to implement authentication usin ...

How can I target and focus on a dynamically generated form in Angular 4/Ionic3?

One of the challenges I'm facing is dealing with dynamically created forms on a page. Each row consists of inputs and a button. Is there a way to select/focus on the input by clicking on the entire row (button)? It should be noted that the number of r ...

Using the Ajax method from a separate class in TypeScript: A step-by-step guide

Recently, I started learning about typescript and ajax. One of the challenges I encountered was while creating a method in typescript for making ajax calls that can be used across classes: myFunc(value: string): JQueryPromise<any> { var dfd = $. ...

Extracting information from JSON using jQuery

this is a sample json object: { "box 1": [{ "difficulty_grade": "5a+" }, { "gym": "New_gym" }, { "route_author": "some author" },]} https://i.sstatic.net/UJodJ.png Here is the code snippet: variable groups contains JSON data as shown in the ...

Cookie-powered JavaScript timer ceases after 60 seconds

I'm having an issue with my countdown timer where it stops counting after just one minute. It seems to pause at 54:00 when I set it for 55 minutes, and at 1:00 when I set it for 2 minutes. Any suggestions on how I can resolve this and make it continue ...

Guide to creating flexible routes with multiple changing parameters in Vue 3 using Vue Router

What is the best way to implement dynamic routes with multiple dynamic parameters in any order using Vue 3 and Vue Router? These parameters should be able to be passed in any order. In our web application, we have over 500 views which makes it impractic ...