0

I've data which I need to break it down into multiple objects and return it.

Below is the sample data

const DATA = {
  text: "\nDo you have questions or comments and do you wish to contact ABC? Please visit our customer support page.",
  EntityRanges: [
    { 
      type:"LINK",
      offset:2,
      length:2, 
      data: { target:null, url:"/index.html", description:null }
    },
    {
      type:"LINK",
      offset:84,
      length:16,
      data: { target:null, url:"/index.html", description:null }
    }
  ]
};

Now, I loop EntityRanges and for each item, I check offset & length and break the text.

Stackblitz Link to my working example.

As per the example, text should be broken down like the following

- Do, type 'link'
- you have questions or comments and do you wish to contact ABC? Please visit our , type 'text'
- customer support, type 'link'
- page., type 'text'

So my expected output should be like this,

[
  {
    "type": "LINK",
    "text": "Do",
    "data": {
      "target": null,
      "url": "/index.html",
      "description": null
    }
  },
  {
    "type": "TEXT",
    "text": "you have questions or comments and do you wish to contact ABC? Please visit our ",
    "data": {}
  },
  {
    "type": "LINK",
    "text": "customer support ",
    "data": {
      "target": null,
      "url": "/index.html",
      "description": null
    }
  },
  {
    "type": "text",
    "text": " page.",
    "data": {},
  }
]

But I'm not getting the expected result. Please Help.


UPDATE

Based on the below solutions, I've still have some issue.

offset Value will always start from 0.

text: "Do you have questions or comments and do you wish to contact KLM? Please visit our customer support page.",

Offset: 0,Length: 2 - Do
Offset: 83, Length: 16 - customer support

But I get the below output,

[
  {
    "type": "link",
    "text": "D",
    "data": {
      "target": null,
      "url": "/index.html",
      "description": null
    }
  },
  {
    "type": "text",
    "text": " you have questions or comments and do you wish to contact ABC? Please visit our",
    "data": {}
  },
  {
    "type": "link",
    "text": " customer suppor",
    "data": {
      "target": null,
      "url": "/index.html",
      "description": null
    }
  },
  {
    "type": "text",
    "text": " page",
    "data": {}
  }
]

Example in the stackBlitz

1
  • @NinaScholz - Could you please help with this question ? Commented Jul 26, 2019 at 9:22

2 Answers 2

1

The following assumes that between every LINK is a TEXT. Further, I couldn't test .flat() due to my browser being ancient, so if somebody could confirm the code to be working, I'd be grateful.

The idea is as follows: We map over entityRanges, constructing two objects on each step. The first being based on the LINK, the second's text based on the difference between the current and the next LINK. We return those two inside an array, so at the end of map we receive an array of array of objects. Thus, we apply flat and voila, an array of objects.

var data = {text:"Do you have questions or comments and do you wish to contact ABC? Please visit our customer support page.",EntityRanges:[{type:"LINK",offset:1,length:2,data:{target:null,url:"/index.html",description:null}},{type:"LINK",offset:84,length:16,data:{target:null,url:"/index.html",description:null}}]};

let res = data.EntityRanges.map((c,i,a) => ([
  {type: c.type, text: data.text.slice(c.offset - 1, c.offset - 1 + c.length),data: c.data},
  {type: "TEXT", text: data.text.slice(c.offset - 1 + c.length, a[i + 1] ? a[i + 1].offset - 1: data.text.length - 1), data: {}}
])).flat();

console.log(res)

Sign up to request clarification or add additional context in comments.

13 Comments

I don't understand this, c,i,a ? c is each range i is index What is a ?
@user007 a is the array we are sequencing. So instead of e.g. saying data.EntityRanges[i + 1] we just say a[i + 1].
I got one issue, {text:"/nDo}, my data is having \n using css I break the line. So using the offset value 2,2. A space is missing. Any idea how to fix it ?
If I do the offset: 2, length: 3 then y is missing out
@user007 I changed some slice parameters, let me know whether this works better.
|
1

Just use it: substring

This is an ugly example just to explain a possible solution.

const DATA = {
  text: "Do you have questions or comments and do you wish to contact ABC? " + 
        "Please visit our customer support page.",
  EntityRanges: [
    { 
      type:"LINK",
      offset:0,
      length:2, 
      data: { target:null, url:"/index.html", description:null }
    },
    {
      type:"LINK",
      offset:83,
      length:16,
      data: { target:null, url:"/index.html", description:null }
    }
  ]
};

var last = 0, result = [];
DATA.EntityRanges.forEach(function(e) {
    var text = DATA.text.substring(last, e.offset);
    if (text != "") {
        result.push({"type": "text", "text": text, data: {}});
    }
    result.push({"type": "link", "text": DATA.text.substring(e.offset, e.offset+e.length), "data": e.data});
    last = e.offset+e.length; 
});

var text = DATA.text.substring(last, DATA.text.length-1);
if (text != "") {
    result.push({"type": "text", "text": text, data: {}});
}

console.log(result);

9 Comments

This works, I get expected output. But can this logic be simplified even further ?
The logic is pretty simple. You split the string and if there is some text in the middle, you put it as text. You could use subfunctions for beautify the code, for example addLink and addText` (or simply addItem(type, text, data)) but the logic is the same.
Before my string starts I've \n, offset:2, length:2 and space is missing out, If i do offset:2, length:3 y is missing out. any idea ?
Does your offset start from 1 or from 0?
offset starts from 0
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.