Skip to content Skip to sidebar Skip to footer

Assigning Dynamic Types To String

Based on the below data I need to break down the text on its offset & length value. const data = { 'text': 'This is sample text', 'range': [{ 'type': 'LINK', 'offse

Solution 1:

Try the following solution:

let inlineEntity = [];
const data = {
    "text": "Do you have questions or comments and do you wish to contact ABC? Please visit our customer support page.",
    "inlineStyleRanges": [{
        "style": "BOLD",
        "offset": 12,
        "length": 20,
        "type": "style"
    }],
    "inlineEntityRanges": [{
        "type": "LINK",
        "offset": 83,
        "length": 16,
        "data": {
            "target": "_self",
            "url": "/index.htm"
        }
    }]
}

constMARKER = '||||';

functionbreakByRanges(ranges, text, tempString) {
    const result = [];
    ranges.forEach((styleRange) => {
        const { offset, length, type } = styleRange;
        const str = text.slice(offset, offset + length + 1);
        tempString = tempString.replace(str, MARKER);
        result.push({ data: str, type });
    })

    return { result, tempString };
}

functionbreakData(data, ranges) {
    const { inlineStyleRanges, inlineEntityRanges, text } = data;
    const result = [];
    let tempText = text;
    let { result: styleResult, tempString: styleTempText } = breakByRanges(inlineStyleRanges, text, tempText);
    tempText = styleTempText;
    result.push(...styleResult);


    let { result: entityResult, tempString: entityTempText } = breakByRanges(inlineEntityRanges, text, styleTempText);
    tempText = entityTempText;
    result.push(...entityResult);

    let orderNumber = 0;
    const textItems = tempText.split(MARKER).map((data, index) => {
        if (result[index]) {
            result[index].order = orderNumber + index + 1;
        }
        const resultData = { data, type: 'text', order: orderNumber + index };
        orderNumber += 1;
        return resultData;
    });
    result.push(...textItems);
    return result.sort((first, second) => first.order - second.order).map((item) => ({ data: item.data, type: item.type }));
}
console.log(JSON.stringify(breakData(data)))

Solution 2:

Another possibility, which is an adaptation of my answer to your previous question, merging the helper functions into the main one and updating to the new combined input format is this:

constbreakData = (data) => {
  const nodes = (data.inlineStyleRanges || [])
    .concat(data.inlineEntityRanges || [])
    .sort(({offset: o1}, {offset: o2}) => o1 - o2)
  const str = data.text || ''const indices = [
    0, 
    ...nodes.reduce((a, {offset, length}) => [...a, offset, offset + length], []),
    str.length
  ]

  constslim = ({offset, length, data, ...rest}) => ({...rest, ...data})

  return indices.slice(1).map((x, i) => [indices[i], x])
    .map(([a, b]) => str.substring(a, b))
    .map((s, i) => i % 2 == 0 
      ? {data: s, type: 'text'}     
      : {data: s, ...slim(nodes[(i - 1) / 2])}
    ).filter(({data}) => data.length > 0)
}

const data = {"text": "Do you have questions or comments and do you wish to contact ABC? Please visit our customer support page.", "inlineEntityRanges": [{"data": {"target": "_self", "url": "/index.htm"}, "length": 16, "offset": 83, "type": "LINK"}], "inlineStyleRanges": [{"length": 21, "offset": 12, "style": "BOLD", "type": "style"}]}

console.log(breakData(data))

It returns more data per node than your request, including the style, url, and target nodes. (There was one oddity in this: I brought the url and target nodes up a level because their parent node was data which conflicted with the data in the output; I don't particularly like this. If you would be happy with text in the output node instead of data, then you could replace it in the ternary, and use this for slim: ({offset, length ...rest}) => ({...rest}))

If you don't want this extended behavior, you can change it by replacing

      : {data: s, ...slim(nodes[(i - 1) / 2])}

with this:

      : {data: s, type: nodes[(i - 1) / 2].type}

(at which point you can also remove slim.)

That might be what you want to do, but the version as I wrote it keeps all sorts of information that might be useful downstream.


(One silly thing: the "text"/"style"/"LINK" capitalization differences really bothers some OCD part of me I didn't know I had. For heaven's sake, change that to "link". ;-) )

Post a Comment for "Assigning Dynamic Types To String"