5

We have a html div (first image) and array of strings (see second image) enter image description here enter image description here

We have to assign the single index like safety[A4] and safety[A5] to the text of div.

But currently it assign two footnote to same text like safety[A5][A4] since safety occurs two times in the html div.

Our current attempt is:

for (var i = 0 ; i < totalNumberOfItemsInCorrelationGrid; i++) {
    var currentDataItem = data[i];
    arr = new Array(currentDataItem.correlation_text, currentDataItem.corr);
    arrOfCorrelatedTextOfCorrelationGrid.push(arr);
}           

// sorting from bigger length of string to smaller length of string
arrOfCorrelatedTextOfCorrelationGrid.sort(function (a, b) {
    return b[0].length - a[0].length; // ASC -> a - b; DESC -> b - a
});

arrOfCorrelatedTextOfCorrelationGrid.forEach(function (item) {
    // item[0] gives value of corelated Text
    // item[1] gives value of corr i.e A1 , A2 etc.

    var _k = item[0].replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$&");
    _k = _k.replace(/^(\w)/, "\\b$1"); //This will add the word boundary at start of word only when it's useful.

    _k = _k.replace(/(\w)$/, "$1\\b"); //This will add the word boundary at end of word only when it's usefull.

    var _corelatedTextwithRegExpression = new RegExp(_k, 'g');
    alert(_corelatedTextwithRegExpression);

    _ObservationText = _ObservationText.replace(
        _corelatedTextwithRegExpression,
        "<span class='selectedTextAuto'>$&[" + item[1] + "]</span>"
    );
});

How can this be done?

Parker
  • 8,539
  • 10
  • 69
  • 98
Shital Kadam
  • 238
  • 2
  • 5
  • 14
  • I can't see the images (my workstation is proxed) could you please explain clearly what did u need? :( – Matteo Rubini Jul 24 '15 at 10:24
  • really briliant question – C Sharper Aug 20 '15 at 12:52
  • I just want to make sure I understand clearly. You have an array that looks like `array = { a1 : values, a2 : student misbehavior, a4 : safety, a5 : safety};` and you want to print the key : value pair like this `values[a1]` into a div as plain text? – Mark Hill Aug 20 '15 at 21:57
  • @Mark Yes, I want to print like that. It is printed like that also. The problem is only for the same word like array = { a4 : safety, a5 : safety}; in this case I just want to to assign the single index like safety[A4] and safety[A5] to the text of div instead of Safety[A4][A5] – Shital Kadam Aug 21 '15 at 11:38
  • i see that there is sort function as well are the values supposed to be sorted by length – Mark Hill Aug 21 '15 at 13:28
  • 1
    Also can you please explain a little further why you have the regex in there and what the purpose of it is? – Mark Hill Aug 21 '15 at 13:49
  • @ShitalKadam, can you share the HTML for this as well? Would make debugging easier :) – Parker Aug 24 '15 at 21:55

1 Answers1

1

Here's a solution that uses a counter object currentOccurrence to keep track of the number of times each word in the <div> has been seen. After each regex replacement this counter is incremented, so the next time that word is seen it uses the next footnote. The function replaceNthMatch is used to selectively replace a specific occurrence of a word.

var data = [{
  corr: 'a1',
  correlation_text: 'values'
}, {
  corr: 'a2',
  correlation_text: 'student misbehavior'
}, {
  corr: 'a4',
  correlation_text: 'safety'
}, {
  corr: 'a5',
  correlation_text: 'safety'
}, {
  corr: 'a6',
  correlation_text: 'safety'
}];

var currentOccurrence = {
  'values': 1,
  'student misbehavior': 1,
  'safety': 1
};

var totalNumberOfItemsInCorrelationGrid = data.length;
var arrOfCorrelatedTextOfCorrelationGrid = [];

var _ObservationText = document.getElementById("text").textContent;

for (var i = 0; i < totalNumberOfItemsInCorrelationGrid; i++) {
  var currentDataItem = data[i];
  arr = new Array(currentDataItem.correlation_text, currentDataItem.corr);
  arrOfCorrelatedTextOfCorrelationGrid.push(arr);
}

// sorting from bigger length of string to smaller length of string
arrOfCorrelatedTextOfCorrelationGrid.sort(function(a, b) {
  return b[0].length - a[0].length; // ASC -> a - b; DESC -> b - a
});

// from https://stackoverflow.com/questions/36183/replacing-the-nth-instance-of-a-regex-match-in-javascript
var replaceNthMatch = function(original, pattern, n, replace) {
  var parts, tempParts;

  if (pattern.constructor === RegExp) {

    // If there's no match, bail
    if (original.search(pattern) === -1) {
      return original;
    }

    // Every other item should be a matched capture group;
    // between will be non-matching portions of the substring
    parts = original.split(pattern);

    // If there was a capture group, index 1 will be
    // an item that matches the RegExp
    if (parts[1].search(pattern) !== 0) {
      throw {
        name: "ArgumentError",
        message: "RegExp must have a capture group"
      };
    }
  } else if (pattern.constructor === String) {
    parts = original.split(pattern);
    // Need every other item to be the matched string
    tempParts = [];

    for (var i = 0; i < parts.length; i++) {
      tempParts.push(parts[i]);

      // Insert between, but don't tack one onto the end
      if (i < parts.length - 1) {
        tempParts.push(pattern);
      }
    }
    parts = tempParts;
  } else {
    throw {
      name: "ArgumentError",
      message: "Must provide either a RegExp or String"
    };
  }

  // Parens are unnecessary, but explicit. :)
  indexOfNthMatch = (n * 2) - 1;

  if (parts[indexOfNthMatch] === undefined) {
    // There IS no Nth match
    return original;
  }

  if (typeof(replace) === "function") {
    // Call it. After this, we don't need it anymore.
    replace = replace(parts[indexOfNthMatch]);
  }

  // Update our parts array with the new value
  parts[indexOfNthMatch] = replace;

  // Put it back together and return
  return parts.join('');
}

arrOfCorrelatedTextOfCorrelationGrid.forEach(function(item) {
  // item[0] gives value of corelated Text
  // item[1] gives value of corr i.e A1 , A2 etc.

  var _k = item[0].replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$&");
  _k = _k.replace(/^(\w)/, "\\b$1"); //This will add the word boundary at start of word only when it's useful.

  _k = _k.replace(/(\w)$/, "$1\\b"); //This will add the word boundary at end of word only when it's usefull.

  var _corelatedTextwithRegExpression = new RegExp(_k, 'g');

  _ObservationText = replaceNthMatch(_ObservationText, item[0], currentOccurrence[item[0]], "<span class='selectedTextAuto'>" + item[0] + "[" + item[1] + "]</span>");
  currentOccurrence[item[0]] ++;
});

document.write(_ObservationText);
#text {
  border: 1px black solid;
}
<div id="text">safety
  <br>
  <br>student misbehavior
  <br>
  <br>safety
  <br>
  <br>values
  <br>
  <br>safety
</div>
Community
  • 1
  • 1
rphv
  • 5,409
  • 3
  • 29
  • 47