Exemplo n.º 1
0
        public void TestLevenshteinDistance()
        {
            var testResult = NfString.LevenshteinDistance("kitten", "sitting");

            Assert.AreEqual(3D, testResult);
            testResult = NfString.LevenshteinDistance("Saturday", "Sunday");
            Assert.AreEqual(3D, testResult);
            testResult = NfString.LevenshteinDistance("Brian", "Brain");
            Assert.AreEqual(2D, testResult);

            Console.WriteLine(NfString.LevenshteinDistance("kitty", "kitten"));
            Console.WriteLine(NfString.LevenshteinDistance("kitty", "kite"));

            //testResult = Etc.LevenshteinDistance("sword", "swath", true);
            //Console.WriteLine(testResult);
        }
Exemplo n.º 2
0
        internal static List <Tuple <Action, int, string, string> > GetClosestMatch(PropertyInfo fromPi, object fromObj, PropertyInfo[] toPis, object toObj, string namePrefix = null, int minLen = 2)
        {
            if (fromPi == null || toPis == null || !toPis.Any())
            {
                return(new List <Tuple <Action, int, string, string> >());
            }

            //we want to map a whole assignment expression to a distance on name
            var ops2Score = new List <Tuple <Action, int, string, string> >();

            Func <PropertyInfo, string, bool, string> getMeasureableName = (gmnPi, prefix, inReverse) =>
            {
                if (gmnPi.Name.Length <= minLen)
                {
                    return(inReverse ? String.Join("", gmnPi.Name, prefix) : String.Join("", prefix, gmnPi.Name));
                }
                return(gmnPi.Name);
            };

            foreach (var toPi in toPis)
            {
                if (NfReflect.IsValueTypeProperty(toPi, true))
                {
                    string toFromTns;
                    Action simpleAssignment = GetSimpleAssignment(toPi, toObj, fromPi, fromObj, out toFromTns);
                    if (String.IsNullOrWhiteSpace(namePrefix))
                    {
                        //for simple value types -to- value types where dest has a very short name
                        namePrefix = toObj.GetType().Name;
                    }
                    var fromPiName        = getMeasureableName(fromPi, namePrefix, false);
                    var cpiName           = getMeasureableName(toPi, namePrefix, false);
                    var fromPiReverseName = getMeasureableName(fromPi, namePrefix, true);
                    var cpiReverseName    = getMeasureableName(toPi, namePrefix, true);

                    var score = (int)NfString.LevenshteinDistance(fromPiName, cpiName);

                    //with short property names, prehaps a better score is when prefix is a suffix instead
                    if (fromPiName != fromPiReverseName || cpiName != cpiReverseName)
                    {
                        var revScore = (int)NfString.LevenshteinDistance(fromPiReverseName, cpiReverseName);
                        if (revScore < score)
                        {
                            score = revScore;
                        }
                    }

                    ops2Score.Add(new Tuple <Action, int, string, string>(simpleAssignment, score, toPi.Name, toFromTns));
                }
                else
                {
                    var toInnerPi = toPi.PropertyType.GetProperties(DefaultFlags);
                    if (!toInnerPi.Any())
                    {
                        continue;
                    }

                    var toInnerObj        = toPi.GetValue(toObj) ?? Activator.CreateInstance(toPi.PropertyType);
                    var innerMeasurements = GetClosestMatch(fromPi, fromObj, toInnerPi, toInnerObj, toPi.Name, minLen);

                    if (!innerMeasurements.Any())
                    {
                        continue;
                    }

                    //these will by def, be the shortest distance
                    foreach (var innerM in innerMeasurements)
                    {
                        //we will chain-link these actions
                        Action complexAction = () =>
                        {
                            innerM.Item1();
                            if (toPi.GetValue(toObj) == null)
                            {
                                toPi.SetValue(toObj, toInnerObj);
                            }
                        };
                        var actionId = String.Join(".", toPi.Name, innerM.Item3);

                        ops2Score.Add(new Tuple <Action, int, string, string>(complexAction, innerM.Item2, actionId, String.Join("`", toPi.PropertyType.FullName, innerM.Item4)));
                    }
                }
            }

            var totalMin = ops2Score.Min(x => x.Item2);
            var closest  = ops2Score.Where(x => x.Item2 == totalMin).ToList();

            return(closest);
        }