1
inputArray = ["z","d"];
inputArray = ["د","ذ"];
function trans(stri){
  inputArray.forEach((value, i) => {
    var next = i + 1;
    a1 = inputArray[i];
    a2 = outputArray[i];
    regex = new XRegExp(a1, "g"); 
    stri = XRegExp.replace(stri, regex, a2, ["all"])
    return stri;
});
}
console.log(trans("dzzd"))

I wanna translate from latin characters to arabic characters, how to use {{Arabic}}?, and I Very new to RegExp or even XRegExp, So how basically i do it? Also I'm very very sorry if im Lack of Experience..

Expected Output = "دذذد"

user _425
  • 17
  • 5
  • 1
    Looks okay, I think all you gotta do is have a variable outside the forEach, and replace it at the end of the loop (instead of returning - that just stops the loop after 1 run). And then after the loop ended, you just return that variable. – Shai Aug 28 '22 at 05:05
  • It said nothing to repeat – user _425 Aug 28 '22 at 05:17
  • @Shai actually this looks okay. He's only using next inside, and it will always be the actual next value given `i` in the forEach callback – Vendetta Aug 28 '22 at 15:24

1 Answers1

1

You can do all the replacements in one pass, making an alternation out of inputArray and using a replacement function to return the appropriate character from outputArray on a match:

function trans(str, from, to) {
  return str.replace(new RegExp(`${from.join('|')}`, 'g'), function(m) {
    return to[from.indexOf(m)];
  });
}

inputArray = ["z", "d"];
outputArray = ["ذ", "د"];
console.log(trans('dzzd', inputArray, outputArray))

Note that if from might contain overlapping values (for example ab and a) you need to sort from and to by the length of the strings in from descending before using them. You can do that with this code:

// create an array of indexes
ids = Array.from({length : from.length}, (_, i) => i)
// sort the indexes by the length of the corresponding string in `from`
ids.sort((a, b) => from[b].length - from[a].length)
// now map from and to to the new order
from = from.map((_, i) => from[ids[i]])
to = to.map((_, i) => to[ids[i]])

This ensures that the regex always matches the longest sequence by preference (since it will come first in the alternation).

You could either insert into the trans function, for example:

function trans(str, from, to) {
  ids = Array.from({ length: from.length }, (_, i) => i)
  ids.sort((a, b) => from[b].length - from[a].length)
  from = from.map((_, i) => from[ids[i]])
  to = to.map((_, i) => to[ids[i]])
  return str.replace(new RegExp(`${from.join('|')}`, 'g'), function(m) {
    return to[from.indexOf(m)];
  });
}

inputArray = ["zz", "d"];
outputArray = ["ذ", "د"];
console.log(trans('dzzd', inputArray, outputArray))

or use it on inputArray and outputArray before you call trans:

function trans(str, from, to) {
  return str.replace(new RegExp(`${from.join('|')}`, 'g'), function(m) {
    return to[from.indexOf(m)];
  });
}

inputArray = ["zz", "d"];
outputArray = ["ذ", "د"];
ids = Array.from({ length: inputArray.length }, (_, i) => i)
ids.sort((a, b) => inputArray[b].length - inputArray[a].length)
inputArray = inputArray.map((_, i) => inputArray[ids[i]])
outputArray = outputArray.map((_, i) => outputArray[ids[i]])

console.log(trans('dzzd', inputArray, outputArray))
Nick
  • 138,499
  • 22
  • 57
  • 95
  • It works, but if it doesn't accept 2 or more characters input.. – user _425 Aug 28 '22 at 05:39
  • @user_425 do you mean translating from (for example) `'ab'` to `'c'`? – Nick Aug 28 '22 at 05:40
  • Yeah. But the "c" is Arabic letter – user _425 Aug 28 '22 at 05:43
  • @user_425 please see my edit – Nick Aug 28 '22 at 05:49
  • Where must i put it? and Doesn't it will change the output because the outputArray doesnt change? – user _425 Aug 28 '22 at 05:54
  • @user_425 please see my new edit. I've corrected the code and shown how to use it. – Nick Aug 28 '22 at 06:11
  • It say nothing to repeat.. also srry for late reply.. – user _425 Aug 28 '22 at 15:07
  • @user_425 that should not be possible with this code if the strings are all letters. Can you please give me the result of `console.log(\`${from.join('|')}\`)` inside the function? – Nick Aug 29 '22 at 00:09
  • Oh, I tried, yeah. But how if I wanna use symbols? – user _425 Aug 29 '22 at 00:53
  • @user_425 it's not really reasonable to keep changing the question as you go. Instead, you should accept the answer you do get (assuming it works) and then ask a new question with the new requirements, referring back to the original as needed). Anyway, if you want to use symbols you will need to escape the strings in `inputArray` using a function like the one in [this answer](https://stackoverflow.com/a/3561711/9473764) with code like `inputArray = inputArray.map(escapeRegex)` – Nick Aug 29 '22 at 00:58