Home > Software design >  Replacing multiple Arrays of character Index Objects into a String in Javascript at Once
Replacing multiple Arrays of character Index Objects into a String in Javascript at Once

Time:06-19

I have a difficult algorithmic problem that I am running into. I have the below long form string that I am feeding into a model that pulls out diseases and drugs from an (anonymous in this case) patient's record. I want to mark it up with html to highlight the diseases and drugs in the record, and I am looking for a reliable mechanism to do this. Right now, I just reverse the arrays and show them one at a time, but ideally, I can show them both at the same time.

Here is what the patient record looks like

Ashton is an 78 year old man with diabetes. He has reported feeling stomach pains when he awakens in the morning and after eating meals which he describes as an aching sensation in his lower abdomen. He identified his diet as mainly consisting of carbs with protein and vegetables as side dishes. Strongly affected by wrist and finger inflammation, he complains that his arthritis is worsening with some reports of dystonia of the fingers, with fingers getting locked in place during daily activities such as brushing teeth and fine motor activities like eating food and washing plates. Santos is taking 20 mg Leflunomide daily and 325mg of Aspirin as needed. He is also on 10 units of Insulin taken after meals and Metformin before meals.

And here is what the diseases and drugs arrays look like from the model

nerArray['diseases']: [
    {
        "word": "dystonia",
        "start": 415,
        "end": 423
    },
    {
        "word": "arthritis",
        "start": 371,
        "end": 380
    },
    {
        "word": "wrist and finger inflammation",
        "start": 318,
        "end": 347
    },
    {
        "word": "stomach pains",
        "start": 68,
        "end": 81
    },
    {
        "word": "diabetes",
        "start": 34,
        "end": 42
    }
]
nerArray['drugs']: [
    {
        "word": "metformin",
        "start": 716,
        "end": 725
    },
    {
        "word": "insulin",
        "start": 686,
        "end": 693
    },
    {
        "word": "aspirin",
        "start": 641,
        "end": 648
    },
    {
        "word": "leflunomide",
        "start": 610,
        "end": 621
    }
]

I also color them:

indexColor['drugs']: 'red',
indexColor['diseases']: 'green,

For just the diseases, the processed string in red highlight would look like this:

Ashton is an 78 year old man with <span  style="color: red; border-radius:5px; border:1px solid red">diabetes</span>. He has reported feeling <span  style="color: red; border-radius:5px; border:1px solid red">stomach pains</span> when he awakens in the morning and after eating meals which he describes as an aching sensation in his lower abdomen. He identified his diet as mainly consisting of carbs with protein and vegetables as side dishes. Strongly affected by <span  style="color: red; border-radius:5px; border:1px solid red">wrist and finger inflammation</span>, he complains that his <span  style="color: red; border-radius:5px; border:1px solid red">arthritis</span> is worsening with some reports of <span  style="color: red; border-radius:5px; border:1px solid red">dystonia</span> of the fingers, with fingers getting locked in place during daily activities such as brushing teeth and fine motor activities like eating food and washing plates. Santos is taking 20 mg Leflunomide daily and 325mg of Aspirin as needed. He is also on 10 units of Insulin taken after meals and Metformin before meals.

and for the drugs in green:

Ashton is an 78 year old man with diabetes. He has reported feeling stomach pains when he awakens in the morning and after eating meals which he describes as an aching sensation in his lower abdomen. He identified his diet as mainly consisting of carbs with protein and vegetables as side dishes. Strongly affected by wrist and finger inflammation, he complains that his arthritis is worsening with some reports of dystonia of the fingers, with fingers getting locked in place during daily activities such as brushing teeth and fine motor activities like eating food and washing plates. Santos is taking 20 mg <span  style="color: green; border-radius:5px; border:1px solid green">Leflunomide</span> daily and 325mg of <span  style="color: green; border-radius:5px; border:1px solid green">Aspirin</span> as needed. He is also on 10 units of <span  style="color: green; border-radius:5px; border:1px solid green">Insulin</span> taken after meals and <span  style="color: green; border-radius:5px; border:1px solid green">Metformin</span> before meals.

Here is the method I use to make that now for one of them, the array is reversed since I do it back to front to make it easier.

processForNerArray(index) { // index is either 'drugs' or 'diseases
      this.processedNote = this.note;
      const seqStart =
        '<span  style="color: '  
        this.indexColor[index]  
        "; border-radius:5px; border:1px solid "  
        this.indexColor[index]  
        '">';
      const seqEnd = "</span>";

      this.nerArray[index].reverse().forEach((nerObj) => {
        this.processedNote =
          this.processedNote.slice(0, nerObj.start)  
          seqStart  
          this.processedNote.slice(
            nerObj.start,
            nerObj.end
          )  
          seqEnd  
          this.processedNote.slice(
            nerObj.end
          );
      });
    },

CodePudding user response:

You can use a "for ... in" to do that. Something like this:

const nerArray = {
  diseases: [
    {
        "word": "dystonia",
        "start": 415,
        "end": 423
    },
    {
        "word": "arthritis",
        "start": 371,
        "end": 380
    },
    {
        "word": "wrist and finger inflammation",
        "start": 318,
        "end": 347
    },
    {
        "word": "stomach pains",
        "start": 68,
        "end": 81
    },
    {
        "word": "diabetes",
        "start": 34,
        "end": 42
    }],
  drugs: [
    {
        "word": "metformin",
        "start": 716,
        "end": 725
    },
    {
        "word": "insulin",
        "start": 686,
        "end": 693
    },
    {
        "word": "aspirin",
        "start": 641,
        "end": 648
    },
    {
        "word": "leflunomide",
        "start": 610,
        "end": 621
  }]
 };
 
 for (let item in nerArray) {
      nerArray[item].forEach(e => console.log(e.word))
      // processForNerArray(item)
 }

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

CodePudding user response:

Instead of making the logic complex, You can simply achieve it by assigning a color property in each object of both the arrays and then concatenate into a single array which contains both diseases and drugs objects.

Now, You can loop over this single array and by using string.replace() method replace all the occurrence of the words with the HTML encoded string.

Live Demo (In Pure JavaScript) :

const diseaseArray = [
    {
        "word": "dystonia",
        "start": 415,
        "end": 423
    },
    {
        "word": "arthritis",
        "start": 371,
        "end": 380
    },
    {
        "word": "wrist and finger inflammation",
        "start": 318,
        "end": 347
    },
    {
        "word": "stomach pains",
        "start": 68,
        "end": 81
    },
    {
        "word": "diabetes",
        "start": 34,
        "end": 42
    }
];

const drugsArray = [
    {
        "word": "Metformin",
        "start": 716,
        "end": 725
    },
    {
        "word": "Insulin",
        "start": 686,
        "end": 693
    },
    {
        "word": "Aspirin",
        "start": 641,
        "end": 648
    },
    {
        "word": "Leflunomide",
        "start": 610,
        "end": 621
    }
];

// Assigning color property with value as 'green' in each object of a diseaseArray.
diseaseArray.forEach(obj => {
    obj.color = 'green'
});

// Assigning color property with value as 'red' in each object of a drugsArray.
drugsArray.forEach(obj => {
    obj.color = 'red'
});

// Now creating a new array by concatinating both the arrays.
const newArr = [...diseaseArray, ...drugsArray];

// Input string
let str = 'Ashton is an 78 year old man with diabetes. He has reported feeling stomach pains when he awakens in the morning and after eating meals which he describes as an aching sensation in his lower abdomen. He identified his diet as mainly consisting of carbs with protein and vegetables as side dishes. Strongly affected by wrist and finger inflammation, he complains that his arthritis is worsening with some reports of dystonia of the fingers, with fingers getting locked in place during daily activities such as brushing teeth and fine motor activities like eating food and washing plates. Santos is taking 20 mg Leflunomide daily and 325mg of Aspirin as needed. He is also on 10 units of Insulin taken after meals and Metformin before meals.';

// Iterate over this new array and replace the sub-string with the HTML.
newArr.forEach(obj => {
    str = str.replace(obj.word, `<span  style="color: ${obj.color}; border-radius:5px; border:1px solid ${obj.color}">${obj.word}</span>`)
});

// Finally binding the result into a HTML DOM.
document.getElementById('result').innerHTML = str;

Live Demo (In Vue.js format) :

new Vue({
  el: '#app',
  data: {
    str: 'Ashton is an 78 year old man with diabetes. He has reported feeling stomach pains when he awakens in the morning and after eating meals which he describes as an aching sensation in his lower abdomen. He identified his diet as mainly consisting of carbs with protein and vegetables as side dishes. Strongly affected by wrist and finger inflammation, he complains that his arthritis is worsening with some reports of dystonia of the fingers, with fingers getting locked in place during daily activities such as brushing teeth and fine motor activities like eating food and washing plates. Santos is taking 20 mg Leflunomide daily and 325mg of Aspirin as needed. He is also on 10 units of Insulin taken after meals and Metformin before meals.',
    diseaseArray: [
      {
        "word": "dystonia",
        "start": 415,
        "end": 423
      },
      {
        "word": "arthritis",
        "start": 371,
        "end": 380
      },
      {
        "word": "wrist and finger inflammation",
        "start": 318,
        "end": 347
      },
      {
        "word": "stomach pains",
        "start": 68,
        "end": 81
      },
      {
        "word": "diabetes",
        "start": 34,
        "end": 42
      }
    ],
    drugsArray: [
      {
        "word": "Metformin",
        "start": 716,
        "end": 725
      },
      {
        "word": "Insulin",
        "start": 686,
        "end": 693
      },
      {
        "word": "Aspirin",
        "start": 641,
        "end": 648
      },
      {
        "word": "Leflunomide",
        "start": 610,
        "end": 621
      }
    ]
  },
  mounted() {
    // Assigning color property with value as 'green' in each object of a diseaseArray.
    this.diseaseArray.forEach(obj => {
      obj.color = 'green'
    });

    // Assigning color property with value as 'red' in each object of a drugsArray.
    this.drugsArray.forEach(obj => {
      obj.color = 'red'
    });

    // Now creating a new array by concatinating both the arrays.
    const newArr = [...this.diseaseArray, ...this.drugsArray];

    // Iterate over this new array and replace the sub-string with the HTML.
    newArr.forEach(obj => {
      this.str = this.str.replace(obj.word, `<span  style="color: ${obj.color}; border-radius:5px; border:1px solid ${obj.color}">${obj.word}</span>`)
    });
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <p v-html="str"></p>
</div>

  • Related