Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I'm missing the (extension) functions isAnyOf(...) and isNoneOf(...) #55115

Open
rekire opened this issue Mar 3, 2024 · 3 comments
Open

I'm missing the (extension) functions isAnyOf(...) and isNoneOf(...) #55115

rekire opened this issue Mar 3, 2024 · 3 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-enhancement A request for a change that isn't a bug

Comments

@rekire
Copy link

rekire commented Mar 3, 2024

I have often the problem that I want to check if a value is one of a very limited list of options. In the past I wrote a extension function with a list of arguments which worked fine for me but was somehow award that this required a list. Now I found randomly a trick in Object.hash(...) which makes it almost perfect. Here is my suggestion for an extension which should be part of dart out of my view:

const Object _notSet = Object();

extension AnyNoneExtension on Object {
  bool isAnyOf(
    Object a,
    Object b, [
    Object c = _notSet,
    Object d = _notSet,
    Object e = _notSet,
    Object f = _notSet,
    Object g = _notSet,
    Object h = _notSet,
    Object i = _notSet,
    Object j = _notSet,
    Object k = _notSet,
    Object l = _notSet,
    Object m = _notSet,
    Object n = _notSet,
    Object o = _notSet,
    Object p = _notSet,
    Object q = _notSet,
    Object r = _notSet,
    Object s = _notSet,
    Object t = _notSet,
    Object u = _notSet,
    Object v = _notSet,
    Object w = _notSet,
    Object x = _notSet,
    Object y = _notSet,
    Object z = _notSet,
  ]) =>
      [
        a,
        b,
        if (c != _notSet) c,
        if (d != _notSet) d,
        if (e != _notSet) e,
        if (f != _notSet) f,
        if (g != _notSet) g,
        if (h != _notSet) h,
        if (i != _notSet) i,
        if (j != _notSet) j,
        if (k != _notSet) k,
        if (l != _notSet) l,
        if (m != _notSet) m,
        if (n != _notSet) n,
        if (o != _notSet) o,
        if (p != _notSet) p,
        if (q != _notSet) q,
        if (r != _notSet) r,
        if (s != _notSet) s,
        if (t != _notSet) t,
        if (u != _notSet) u,
        if (v != _notSet) v,
        if (w != _notSet) w,
        if (x != _notSet) x,
        if (y != _notSet) y,
        if (z != _notSet) z,
      ].contains(this);

  bool isNoneOf(
    Object a,
    Object b, [
    Object c = _notSet,
    Object d = _notSet,
    Object e = _notSet,
    Object f = _notSet,
    Object g = _notSet,
    Object h = _notSet,
    Object i = _notSet,
    Object j = _notSet,
    Object k = _notSet,
    Object l = _notSet,
    Object m = _notSet,
    Object n = _notSet,
    Object o = _notSet,
    Object p = _notSet,
    Object q = _notSet,
    Object r = _notSet,
    Object s = _notSet,
    Object t = _notSet,
    Object u = _notSet,
    Object v = _notSet,
    Object w = _notSet,
    Object x = _notSet,
    Object y = _notSet,
    Object z = _notSet,
  ]) =>
      !isAnyOf(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z);
}

Usage sample:

final weekday = currentWeekday();
if (weekday.isAnyOf('Monday', 'Sunday') && weekday.isNoneOf('Saturday', 'Friday')) {
  print('Do something fancy');
}

I'm curious what you think about it.

@Wdestroier
Copy link

Did you try const {'Monday', 'Sunday'}.contains(weekday)? It should be more performant.

main() {
  var weekday = 'Monday';
  print(const {'Monday', 'Tuesday'}.contains(weekday)); // true
  
  weekday = 'Sunday';
  print(const {'Monday', 'Tuesday'}.contains(weekday)); // false
}

You may want to move this request to the dart-lang/sdk repository.

@lrhn
Copy link
Member

lrhn commented Mar 5, 2024

I'd probably use the constant set too, if the values can be constant, at least unless performance is very, very important, and I know something that can make the check more efficient than a hash set lookup (or a linear v == c1 || v == c2 || ... check).

I'd definitely not create a list, or even a set, for every call and then do a contains on that. Doing linear work to set up an efficient one-use contains is strictly worse than just v == v1 || v == v2 || ... || v == vn.

A more direct approach could be:

extension AnyOf on Object {
  bool anyOf(Object v1, Object v2,
      [Object? v3,
      Object? v4,
      Object? v5,
      Object? v6,
      Object? v7,
      Object? v8,
      Object? v9,
      Object? v10]) {
    return this == v1 ||
        this == v2 ||
        this == v3 ||
        v3 != null &&
            (this == v4 ||
                v4 != null &&
                    (this == v5 ||
                        v5 != null &&
                            (this == v6 ||
                                v6 != null &&
                                    (this == v7 ||
                                        v7 != null &&
                                            (this == v8 ||
                                                v8 != null &&
                                                    (this == v9 ||
                                                        v9 != null &&
                                                            (this == v10)))))));
  }
}

@lrhn lrhn transferred this issue from dart-lang/language Mar 6, 2024
@lrhn lrhn added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-enhancement A request for a change that isn't a bug labels Mar 6, 2024
@Wdestroier
Copy link

I enjoy the performance improvement and the code may look more idiomatic. Reusing the code should be simple too. For example: by creating an isWeekend function. The major problem would be polluting the Object namespace I guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

3 participants