Skip to content

how to convert javascript code functions to dart?

I have a code written in javascript and I am trying to transcribe it to dart this is my javascript code:

var Fn = {
    validateRut : function (rutComplete) {
        rutComplete = rutComplete.replace("‐","-");
        if (!/^[0-9]+[-|‐]{1}[0-9kK]{1}$/.test( rutComplete ))
            return false;
        var tmp     = rutComplete.split('-');
        var digv    = tmp[1]; 
        var rut     = tmp[0];
        if ( digv == 'K' ) digv = 'k' ;
        
       return (Fn.dv(rut) == digv );
    },
    dv : function(T){
        var M=0,S=1;
        for(;T;T=Math.floor(T/10)) 
            S=(S+T%10*(9-M++%6))%11;
        
        return S?S-1:'k';
    }
}

but I have problems in the for loop part since I do not understand well how dart works, this is the code that I have been working on

class Rut{
  static bool validate(String rutComplete){
    rutComplete = rutComplete.replaceAll("‐","-");
    RegExp value=new RegExp(r'^[0-9]+[-|‐]{1}[0-9kK]{1}$');
   
    if (!value.hasMatch(rutComplete))
          return false;
    var tmp     = rutComplete.split('-');
        var digv    = tmp[1]; 
        var rut     = tmp[0];
        if ( digv == 'K' ) digv = 'k' ;
        return (dv(rut) == digv);
  }

  static String dv(String rut){
    var M=0,S=1;

   
    for(;int.parse(rut);rut=(int.parse(rut)/10).floor()) 
            S=(S+int.parse(rut)%10*(9-M++%6))%11;

  var result = S > 0 ? S-1:"k"; 
  return  result.toString();

}
}

I really appreciate your help

Answer

Your code is almost right as a direct translation from JavaScript.

Javascript has untyped variables and automatic coercion between types, so the dv method’s parameter T starts out as a string, and is then converted to a number by T = Math.floor(T / 10), because / automatically converts its operands to numbers.

Dart does not have coercion, and String does not have a / operator, so that won’t work. You need to introduce a new variable to hold the number. Something like:

static String dv(String rut){
  var m = 0, s = 1, t = int.parse(rut);
  for(;t > 0; t ~/= 10) {
    s = (s + t % 10 * (9 - m++ % 6)) % 11;
  }
  var result = s > 0 ? (s - 1).toString() : "k"; 
  return result;
}

Or, if you want to optimize it a bit, you can extract the digits directly from the string:

static String dv(String rut){
  var m = 0, s = 1;
  for (var i = rut.length - 1; i >= 0; i--) {
    var digit = rut.codeUnitAt(i) ^ 0x30;
    s = (s + digit * (9 - m++ % 6)) % 11;
  }
  var result = s > 0 ? (s-1).toString() : "k"; 
  return result;
}

Also, the first method can be optimized and simplified as well:

static final _validateRE = RegExp(r'^(d+)[u2010-]([dkK])$');
static bool validate(String rutComplete){
  var match = _validateRE.firstMatch(rutComplete);
  if (match == null) return false;
  var digv = match[2]!;  // remove `!` if not using null safety
  if (digv == 'K') digv = 'k';
  var rut = match[1]!;   // ditto
  return dv(rut) == digv;
}

This avoids using both a RegExp and a split, after the RegExp has already found all the parts. By making the RegExp capture the matches, you can get the parts directly from the match. Also, by reusing the RegExp, you avoid creating a new RegExp object for each call.

Replacing the u2010 dash with a normal dash would mean you don’t have to match against both in the RegExp. Since it doesn’t matter to check for one more character, I removed the replace. I also removed the | from [u2010|-] since that actually matches |, and as I read it (one quick google), only dashes are allowed in RUTs. It’s either (u2010|-) or [u2010-], the | isn’t needed inside a character class. The {1} in the RegExp means “repeat one time”, so it makes no difference to remove them.

If performance is really important, I’d probably do the checking without creating any new substrings at all, working entirely on the original string, but for normal usage, this should be fine.