Coder Social home page Coder Social logo

thadeu / recollect-array Goto Github PK

View Code? Open in Web Editor NEW
8.0 1.0 0.0 55 KB

๐Ÿ”ƒ Simple wrapper to filter array using Ruby and simple predicate conditions

Home Page: https://rubygems.org/gems/recollect-array

License: MIT License

Ruby 99.51% Shell 0.49%
ruby gems array array-filter array-like collection-filters filter recollect-array

recollect-array's Introduction

๐Ÿ”ƒ recollect-array

Simple wrapper to filter array using Ruby and simple predicate conditions

Gem Build Status

Motivation

Because in sometimes, we need filter array passing conditions. This gem simplify this work.

Documentation

Version Documentation
unreleased https://github.com/thadeu/recollect-array/blob/main/README.md

Table of Contents

Compatibility

kind branch ruby
unreleased main >= 2.5.8, <= 3.1.x

Installation

Use bundle

bundle add recollect-array

or add this line to your application's Gemfile.

gem 'recollect-array'

and then, require module

require 'recollect/array'

Configuration

Without configuration, because we use only Ruby. โค๏ธ

Availables Predicates for all values

Type Suffix Value
Equal eq Anywhere
NotEqual noteq Anywhere
Contains cont Anywhere
NotContains notcont Anywhere
Included in Anywhere
NotIncluded notin Anywhere
Start start Anywhere
NotStart notstart Anywhere
End end Anywhere
NotEnd notend Anywhere
LessThan lt Anywhere
LessThanEqual lteq Anywhere
GreaterThan gt Anywhere
GreaterThanEqual gteq Anywhere

Availables Predicates only when value is Hash

๐Ÿ’ก Below predicates works only when value is Hash

Type Suffix Value
NotEqual not_eq Hash
NotContains not_cont Hash
NotIncluded not_in Hash
NotStart not_start Hash
NotEnd not_end Hash

Usage

Think that your data seems like this.
data = [
  {
    id: 1,
    name: 'Test #1',
    email: '[email protected]',
    schedule: { all_day: true },
    numbers: %w[1 2],
    active: true,
    count: 9
  },
  {
    id: 2,
    name: 'Test #2',
    email: '[email protected]',
    schedule: { all_day: false },
    numbers: %w[3 4],
    active: true,
    count: 10
  },
  {
    id: 3,
    name: 'Test #3',
    email: '[email protected]',
    schedule: { all_day: false },
    numbers: %w[5 6],
    active: false,
    count: 99
  }
]

You can use one or multiples predicates in your filter. We see some use cases.

Flexible Use Case (Hash)

Equal

filters = {
  active: {
    eq: true
  }
}

collection = Recollect::Array.filter(data, filters)

NotEqual

filters = {
  active: {
    # noteq or not_eq
    not_eq: true
  }
}

collection = Recollect::Array.filter(data, filters)

Nested Hash Paths

filters = {
  'schedule.all_day': {
    eq: true
  }
}

collection = Recollect::Array.filter(data, filters)

Nested Array Paths

Note the .0 ๐ŸŽ‰

filters = {
  'numbers.0': {
    eq: '3'
  }
}

collection = Recollect::Array.filter(data, filters)
filters = {
  numbers: {
    in: '3' # or in: ['3']
  }
}

collection = Recollect::Array.filter(data, filters)

Using default Equal predicate.

Recollect::Array.filter(data, numbers: 3)

Recollect::Array.filter(data, active: true)

Recollect::Array.filter(data, id: 3)

If array, you can navigate into self, using property.NUMBER.property

data = [
  {
    schedules: [
      {
        opened: true,
        all_day: true
      },
      {
        opened: false,
        all_day: true
      }
    ]
  },
  {
    schedules: [
      {
        opened: false,
        all_day: true
      },
      {
        opened: false,
        all_day: true
      }
    ]
  }
]

filters = {
  'schedules.0.opened': {
    eq: true
  }
}

# OR

filters = {
  'schedules[0]opened': {
    eq: true
  }
}

# OR

filters = {
  'schedules.[0].opened': {
    eq: true
  }
}

collection = Recollect::Array.filter(data, filters)

# [{ schedules: [{ opened: true, all_day: true }, { opened: false, all_day: true }] }]

Amazing, you can pass a Callable value as value, like this.

filters = {
  'schedules.[0].opened': {
    eq: -> { true }
  }
}

# OR a Module

module ActiveTruthy
  def self.call = true
end

module NumbersAvailable
  def self.call = %w[1 2]
end

filters = {
  'schedules.[0].opened': {
    eq: ActiveTruthy
  },
  numbers: {
    in: NumbersAvailable
  }
}

# OR a Class

class ActiveFalsey
  def self.call = false
end

filters = {
  'schedules.[0].opened': {
    eq: ActiveFalsey
  }
}

collection = Recollect::Array.filter(data, filters)

Combine conditions

Yes, you can combine one or multiple predicates to filter you array.

filters = {
  active: { eq: true },
  numbers: {
    in: %w[5],
    not_in: '10'
  },
  email: {
    cont: 'email1',
    not_cont: '@gmail'
  },
  'schedule.all_day': {
    in: [true, false]
  }
}

collection = Recollect::Array.filter(data, filters)

Querystring Use Case

Equal

filters = { active_eq: true }

collection = Recollect::Array.filter(data, filters)

NotEqual

filters = { active_noteq: true }

collection = Recollect::Array.filter(data, filters)

Nested Hash Paths

filters = { 'schedule.all_day_eq': false }

collection = Recollect::Array.filter(data, filters)

Nested Array Paths

Note the .0 ๐ŸŽ‰

filters = { 'numbers.0_eq': '3' }

collection = Recollect::Array.filter(data, filters)
filters = { numbers_in: ['1'] }

collection = Recollect::Array.filter(data, filters)

expect(collection.size).to eq(1)

Combine conditions

Yes, you can combine one or multiple predicates to filter you array.

filters = {
  active_noteq: true,
  numbers_in: %w[5],
  email_cont: 'test3',
  'schedule.all_day_eq': false
}

collection = Recollect::Array.filter(data, filters)

Receive querystring in your route

Like Ransack, imagine that you receive an querystring and you want to filter your Array. So, you can to do something like this.

โš ๏ธ But security is your responsability, ok? Let's go!

# receive querystring in your route
querystring = "active_noteq=true&numbers_in=5&email_cont=test3&schedule.all_day_eq=false"

# parse querystring and transform to Hash
params = URI.decode_www_form(querystring).to_h

# filter your collection using params directly.
collection = Recollect::Array.filter(data, filters)

# Beautiful, right? ๐ŸŽ‰

Utilities

Recollect::Hashie.get(hash, path)

user = {
  id: 1,
  name: 'Test #1',
  email: '[email protected]',
  schedule: { all_day: true },
  numbers: %w[1 2],
  active: true,
  count: 9
}

result = Recollect::Hashie.get(user, 'id')
-> 1

result = Recollect::Hashie.get(user, 'schedule.all_day')
-> true

result = Recollect::Hashie.get(user, 'numbers')
-> ['1', '2']

result = Recollect::Hashie.get(user, 'numbers.0')
-> 1

result = Recollect::Hashie.get(user, 'numbers[0]')
-> 1

result = Recollect::Hashie.get(user, 'numbers[0][1]')

result = Recollect::Hashie.get(user, 'numbers.[0].[1]')

Recollect::Array.pluck(array, path)

users = [
  {
    id: 1,
    name: 'Test #1',
    email: '[email protected]',
    schedule: { all_day: true },
    numbers: %w[1 2],
    active: true,
    count: 9
  },
  {
    id: 2,
    name: 'Test #1',
    email: '[email protected]',
    schedule: { all_day: true },
    numbers: %w[1 2],
    active: true,
    count: 9
  }
]

result = Recollect::Array.pluck(users, 'id')
$ -> [1, 2]

result = Recollect::Array.pluck(users, 'schedule.all_day')
$ -> [true, true]

โฌ†๏ธ ย Back to Top

Development

After checking out the repo, run bin/setup to install dependencies. Then, run bundle exec rspec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/thadeu/recollect-array. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

recollect-array's People

Contributors

thadeu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

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.