חיפוש מעבר קטע באזור מסוים במחרוזת
-
שכחת אינדקסרים, וקצת עיצוב הזחות (עד מתי? סה"כ קיצור מקשים!):
function getClosetMatch(theString, matchSerch, goal) { let prevPos = [-1, 0]; theString.replace(new RegExp(matchSerch, 'g'), function(match, currPos){ prevPos[0] = Math.abs(currPos - goal) < Math.abs(prevPos[0] - goal) ? currPos : prevPos[0]; currPos += match.length; prevPos[1] = Math.abs(currPos - goal) < Math.abs(prevPos[1] - goal) ? currPos : prevPos[01]; return match; }); return prevPos; }
-
בסוף עשיתי אחרת, זה נכון יותר כיון שזה 2 צורות הסתכלות על אותו חיפוש.
function getClosetMatch(theString, matchSerch, goal) { let prevPos = [-1, 0]; theString.replace(new RegExp(matchSerch, 'g'), function(match, currPos){ prevPos[0] = Math.abs(currPos - goal) < Math.abs(prevPos[0] - goal) ? currPos : prevPos[0]; prevPos[1] = prevPos[0] + match.length; return match; }); return prevPos; }
-
אני חשבתי לייעל את זה, כי בדרך של הריפלייס על כרחך הוא עובר על כל התוצאות כולל אחרי שאתה בודאי לא צריך. שהרי אחרי התוצאה הראשונה שאינדקס ההתחלה שלה גדול מgoal כבר מיותר להמשיך.
לכן אני כתבתי ככה:function getClosetMatch(theString, matchSerch, goal) { let prevPos = [-1, 0]; let reg = new RegExp(matchSerch, 'g'); let lastResult = null; while((lastResult = reg.exec(theString)) != null){ let currPos = reg.lastIndex; if(currPos < goal) prevPos = [currPos, lastResult.length]; else { if((prevPos[0] - goal) > (goal - currPos)) prevPos = [currPos, lastResult.length]; break; } } return prevPos; }
זה ארוך יותר, מה שנקרא "לפרנציפ"...
יש פה רווח שולי שלא צריך גם את הMath.abs, שהרי ממילא בדקתי אם הוא קטן מgoal... נו נו -
זה זה
function getClosetMatch(theString, matchSerch, goal) { let prevPos = [-1, 0]; let reg = new RegExp(matchSerch, 'g'); let lastResult = null; while((lastResult = reg.exec(theString)) != null){ let currPosAfterFind = reg.lastIndex; let currPosBeforeFind = lastResult.index; if(currPosAfterFind < goal || prevPos[0]==-1) { prevPos = [currPosBeforeFind, currPosAfterFind]; } else { if((prevPos[1] - goal) < (goal - currPosAfterFind)) { prevPos = [currPosBeforeFind, currPosAfterFind]; } break; } } return prevPos; }
-
לגבי הקוד הראשון עליך לשנות מmatch[1] לmatch[0]
הסביר: הexec כל פעם מחזיר את ההופעה הראשונה אחרי הlastIndex ומעדכן את הlastIndex למיקום הרלוונטי. הוא מחזיר את ההופעה שנמצאה בצורת מערך, רק עבור הקבוצות. במקרה שלך אין קבוצות = מעניין אותך רק הקבוצה הראשונה שמכילה את כלל התוצאות.