Git Product home page Git Product logo

dart-fuzzywuzzy's Introduction

FuzzyWuzzy

Tests Coverage Status

This is a Dart port of the popular FuzzyWuzzy python package. This algorithm uses Levenshtein distance to calculate similarity between strings.

I personally needed to use this for my own search algorithms, and there weren't any packages as good as my experience with FuzzyWuzzy was, so here we are. Enjoy!

  • Just one dependency (collection).
  • Pure Dart implementation of the superfast python-Levenshtein.
  • Simple to use.
  • Lightweight.
  • Massive props to the folks over at seatgeek for coming up with the algorithm.

Get started

Add dependency

dependencies:
  fuzzywuzzy: <latest version>

Usage

First, import the package

import 'package:fuzzywuzzy/fuzzywuzzy.dart'

Simple ratio

ratio("mysmilarstring", "myawfullysimilarstirng") // 72
ratio("mysmilarstring", "mysimilarstring")        // 97

Partial ratio

partialRatio("similar", "somewhresimlrbetweenthisstring") // 71

Token sort ratio

tokenSortPartialRatio("order words out of", "words out of order") // 100
tokenSortRatio("order words out of","  words out of order")       // 100

Token set ratio

tokenSetRatio("fuzzy was a bear", "fuzzy fuzzy fuzzy bear")         // 100
tokenSetPartialRatio("fuzzy was a bear", "fuzzy fuzzy fuzzy bear")  // 100

Weighted ratio

weightedRatio("The quick brown fox jimps ofver the small lazy dog", "the quick brown fox jumps over the small lazy dog") // 97

Extract

extractOne(
        query: 'cowboys',
        choices: [
          'Atlanta Falcons',
          'New York Jets',
          'New York Giants',
          'Dallas Cowboys'
        ],
        cutoff: 10,
      ) // (string Dallas Cowboys, score: 90, index: 3)
extractTop(
        query: 'goolge',
        choices: [
          'google',
          'bing',
          'facebook',
          'linkedin',
          'twitter',
          'googleplus',
          'bingnews',
          'plexoogl'
        ],
        limit: 4,
        cutoff: 50,
      ) // [(string google, score: 83, index: 0), (string googleplus, score: 75, index: 5)]
extractAllSorted(
        query: 'goolge',
        choices: [
          'google',
          'bing',
          'facebook',
          'linkedin',
          'twitter',
          'googleplus',
          'bingnews',
          'plexoogl'
        ],
        cutoff: 10,
      ) // [(string google, score: 83, index: 0), (string googleplus, score: 75, index: 5), (string plexoogl, score: 43, index: 7), (string bingnews, score: 29, index: 6), (string linkedin, score: 29, index: 3), (string facebook, score: 29, index: 2), (string bing, score: 23, index: 1), (string twitter, score: 15, index: 4)]
extractAll(
        query: 'goolge',
        choices: [
          'google',
          'bing',
          'facebook',
          'linkedin',
          'twitter',
          'googleplus',
          'bingnews',
          'plexoogl'
        ],
        cutoff: 10,
      ) // [(string google, score: 83, index: 0), (string bing, score: 23, index: 1), (string facebook, score: 29, index: 2), (string linkedin, score: 29, index: 3), (string twitter, score: 15, index: 4), (string googleplus, score: 75, index: 5), (string bingnews, score: 29, index: 6), (string plexoogl, score: 43, index: 7)]

Extract using any a list of any type

All extract methods can receive List<T> and return List<ExtractedResult<T>>

class TestContainer {
  final String innerVal;
  TestContainer(this.innerVal);
}

extractOne<TestContainer>(
        query: 'cowboys',
        choices: [
          'Atlanta Falcons',
          'New York Jets',
          'New York Giants',
          'Dallas Cowboys'
        ].map((e) => TestContainer(e)).toList(),
        cutoff: 10,
        getter: (x) => x.innerVal
      ).toString(); // (string Dallas Cowboys, score: 90, index: 3)

dart-fuzzywuzzy's People

Contributors

kal-elx avatar renovate[bot] avatar semantic-release-bot avatar sphericalkat avatar wer-mathurin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

dart-fuzzywuzzy's Issues

Strong type example

@SphericalKat,

First, that's very responsive to update the library :-) Many thanks.

If I can suggest something to update the doc to reflect better type safe code.
Otherwise the compiler will not warn you that you may pass a list of the wrong type and the getter can throw an error if casting the wrong type. You can omit the class type in the function, because it knows the type of the Function param.

Documentation should be for typed fonctions:

class TestContainer {
  final String innerVal;
  TestContainer(this.innerVal);
}

extractOne<TestContainer>(
        query: 'cowboys',
        choices: [
          'Atlanta Falcons',
          'New York Jets',
          'New York Giants',
          'Dallas Cowboys'
        ].map((e) => TestContainer(e)).toList(),
        cutoff: 10,
        getter: (x) => x.innerVal
      ).toString(); // (string Dallas Cowboys, score: 90, index: 3)

📳RangeError (index): Invalid value: Not in inclusive range 0..26: 30 👀

Error 🙄

======== Exception caught by widgets library =======================================================
The following RangeError was thrown building _SearchPage<String>(dirty, dependencies: [_LocalizationsScope-[GlobalKey#e1ca9], _InheritedTheme], state: _SearchPageState<String>#62f97):
RangeError (index): Invalid value: Not in inclusive range 0..26: 30

The relevant error-causing widget was: 
  MaterialApp MaterialApp:file:///F:/Marketing-App/lib/main.dart:8:10
When the exception was thrown, this was the stack: 
#0      List.[] (dart:core-patch/growable_array.dart:254:60)
#1      DiffUtils.levEditDistance (package:fuzzywuzzy/diffutils/diff_utils.dart:600:37)
#2      DiffUtils.getRatio (package:fuzzywuzzy/diffutils/diff_utils.dart:732:24)
#3      SimpleRatio.apply (package:fuzzywuzzy/ratios/simple_ratio.dart:7:29)
#4      ratio (package:fuzzywuzzy/fuzzywuzzy.dart:14:24)
#5      WeightedRatio.apply (package:fuzzywuzzy/algorithms/weighted_ratio.dart:26:16)
#6      Extractor.extractWithoutOrder (package:fuzzywuzzy/extractor.dart:27:24)
#7      extractAll (package:fuzzywuzzy/fuzzywuzzy.dart:94:20)

My FuzzyWuzzy Implementation

List<String> testing =
          extractAll(query: query, choices: suggestions, cutoff: 10)
              .map((e) => e.choice.toString())
              .toList();

I am currently using fuzzy search inside Search Delegate flutter , but i don't think issue is through that as you'll see;

Suggestions (choice list)

Sugesstions are my choices and its a large list :

[Test Title, YO, HELLO TITLE, Test title, Test title, Test title isha, Test title, Top 10 Highest Paying Jobs in India 2021, NEET Preparation Tips, Syllabus & Best Books for 2021, Best Books for JEE Preparation 2021, 2022, 2023 [Main + Advanced], Best Indian Romance Novels | A List of 10 Romantic Books, All the Harry Potter Books in Order: Your J.K. Rowling Reading List, Top 5 Sci Fi Books Ever Written Of All Time | Must Read, NEET PG 2021: Admit Card to be released on April 12. Check details, NTA Extends JEE Main 2021 April Application Correction Date - Check Details Here, TOP REASONS TO BUY SECOND HAND BOOKS ONLINE, KNOW HOW THE HABIT OF READING BOOKS CAN CHANGE YOUR LIFE!, Why to buy pre-loved books, This comic collector has one of the largest collections of vintage India-published comic books, As book publishing shrinks during the pandemic, how are India’s printing presses coping, Vikram Seth’s A Suitable Boy will soon stream on Netflix; here’s what the novel is all about, 10 Most Controversial Nov

Remarks

suggestions list have string with greater length - I tried by using sub string of each string in suggestions , issue remained same
Also suggestion is of large length

Additional context

flutter doctor

F:\flutter_ecommerce_app>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
 Flutter (Channel stable, 2.5.0, on Microsoft Windows [Version 10.0.19043.1151], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.60.1)
[√] Connected device (3 available)

• No issues found!

flutter doctor verbose

F:\Fluttter Apps\customer>flutter doctor -v
[√] Flutter (Channel stable, 2.5.0, on Microsoft Windows [Version 10.0.19043.1151], locale en-US)
    • Flutter version 2.5.0 at D:\src\flutter\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4cc385b4b8 (13 days ago), 2021-09-07 23:01:49 -0700
    • Engine revision f0826da7ef
    • Dart version 2.14.0

[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at C:\Users\LAKHN KUMAWAT\AppData\Local\Android\sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Android Studio (version 2020.3)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)

[√] VS Code (version 1.60.1)
    • VS Code at C:\Users\LAKHN KUMAWAT\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension can be installed from:
       https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (3 available)
    • RMX1851 (mobile) • 4e5981a2 • android-arm64  • Android 11 (API 30)
    • Chrome (web)     • chrome   • web-javascript • Google Chrome 93.0.4577.82
    • Edge (web)       • edge     • web-javascript • Microsoft Edge 93.0.961.47

• No issues found!

flutter version

F:\flutter_ecommerce_app>flutter --version
Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4cc385b4b8 (9 days ago) • 2021-09-07 23:01:49 -0700
Engine • revision f0826da7ef
Tools • Dart 2.14.0

@SphericalKat Please help me if you get my issue 🥺.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/release-ghr.yml
  • actions/checkout v3
  • actions/setup-node v2
.github/workflows/test.yml
  • actions/checkout v3
  • dart-lang/setup-dart v1
  • actions/checkout v3
  • dart-lang/setup-dart v1
  • coverallsapp/github-action v2
npm
package.json
  • @semantic-release/changelog ^5.0.1
  • @semantic-release/commit-analyzer ^8.0.1
  • @semantic-release/git ^9.0.1
  • @semantic-release/npm ^7.1.3
  • @semantic-release/release-notes-generator ^9.0.3
  • semantic-release ^17.4.7
  • semantic-release-dart ^1.0.0-alpha.1
pub
pubspec.yaml
  • collection ^1.16.0
  • test ^1.24.3
  • lints ^2.1.1
  • analyzer ^5.13.0
  • dart >=3.0.0 <4.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

GPLv2 License

Can somebody explain to me what this license means for usage in my proprietary commercial Flutter project? I known there exists a "library exception" in the GPLv2. Does it apply to this package when I use it in my project? Unfortunately it is not possible for me to release the source code of the app where I plan to use this package.

Thank you!

Search multiple properites in object

Is it possible to specify multiple object properties in the getter? For example, I have a list of user objects and I'm looking to do a search on the username property and name property of a user object.

How to extract String from ExtractedResults<String> object

All i want is list of strings and the thing i get by using extractop is list of type extracted results strings . I stack overflowed searched here and there how to convert it into list of string , please help .....


Here Suggestions is my list of strings

List<String> testing =
        extractTop(query: query, choices: suggestions,
          limit: 4,
          cutoff: 50,
           ).map((e) => (e).toString()).toList();
    print(testing);

Output i get by printing

[(string Dallas Cowboys, score: 90, index: 3),(string cow animal, score: 87, index: 5)] 

Like this


I only want Particular String Dallas Cowboys or cow animal please help !

Add Generics for passing other kind of list

@SphericalKat,

very good first implementation and easy to use;

Add the capability of passing:
List instead of a list of String

When providing a generic List, we must provide a getter function for the search => String Function(T)

You can also parametrize the class ExtractedResult and add a property let say
final T original;

By doing this we would not require to convert the original list of Something to a list a String and convert it again to a List of Something.

Anoying exception raised in debug mode: extractTop generate bad state exception

@SphericalKat
This is due to this method: The removeFirst can throw an exception because it can be empty. So this can be annoying when debugging with the catch all exceptions enabled!

List<ExtractedResult<T>> _findTopKHeap<T>(
      List<ExtractedResult<T>> arr, int k) {
    var pq = PriorityQueue<ExtractedResult<T>>();

    for (var x in arr) {
      if (pq.length < k) {
        pq.add(x);
      } else if (x.compareTo(pq.first) > 0) {
        pq.removeFirst();
        pq.add(x);
      }
    }
    var res = List<ExtractedResult<T>>.empty(growable: true);
    for (var i = k; i > 0; i--) {
      try {
        **var polled = pq.removeFirst();**
        res.add(polled);
      } catch (e) {
        continue;
      }
    }
    return res;
  }

What about doing a little check before, instead of relying on the exception throw? Seems cleaner to me. What do you think?

 List<ExtractedResult<T>> extractTop<T>(
      String query, List<T> choices, Applicable func, int limit,
      [String Function(T obj)? getter]) {
    var best = extractWithoutOrder(query, choices, func, getter);
    var results = _findTopKHeap(best, limit);
    return results.reversed.toList();
  }

  List<ExtractedResult<T>> _findTopKHeap<T>(
      List<ExtractedResult<T>> arr, int k) {
    var pq = PriorityQueue<ExtractedResult<T>>();

    for (var x in arr) {
      if (pq.length < k) {
        pq.add(x);
      } else if (x.compareTo(pq.first) > 0) {
        pq.removeFirst();
        pq.add(x);
      }
    }
    var res = List<ExtractedResult<T>>.empty(growable: true);
    for (var i = k; i > 0; i--) {
      if (pq.isNotEmpty) {
        res.add(pq.removeFirst());
      }
    }
    return res;
  }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.