pie icon indicating copy to clipboard operation
pie copied to clipboard

func Find(ElementType) int

Open elliotchance opened this issue 5 years ago • 10 comments

Find will return the index of the first element that matches, or -1 if none match.

elliotchance avatar May 09 '19 00:05 elliotchance

Hey there,

You mean something like First, but in this case, it will return the index of the first match instead of the element, right? Something like findIndex for JS (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)

The way I read this it would be something like:

package main

import (
    "fmt"
    "strings"

    "github.com/elliotchance/pie/pie"
)

func main() {
    nameIdx := pie.Strings{"Bob", "Sally", "John", "Jane"}.
        Find(func (name string) bool {
            return name == "John"
        })

    fmt.Println("John found on position: " + nameIdx) // "2"
}

Or will it be something like find from JS? (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

I'm excited to help this pie to get bigger 😅, but I'll wait to hear back from you to submit a PR.

danielpsf avatar May 09 '19 11:05 danielpsf

You are right. First and Last are better names.

They will take a value as the argument and return the respective index. When a callback is used instead of a value we append "Using", like:

nameIdx := pie.Strings{"Bob", "Sally", "John", "Jane"}.
    First("John")
nameIdx := pie.Strings{"Bob", "Sally", "John", "Jane"}.
    FirstUsing(func (name string) bool {
        return name == "John"
    })

I'm glad you are so excited to contribute! I'm looking forward to the PR.

elliotchance avatar May 09 '19 23:05 elliotchance

Oops, I should have read my own documentation. First and Last are already taken. So FindFirst and FindLast are more appropriate.

elliotchance avatar May 09 '19 23:05 elliotchance

Ops, do you want to make both FindFirst and FindLast part of the same PR or do you want me to update the description to say that I'm just adding FindFirst as part of #140 and not actually closing this feature request?

danielpsf avatar May 13 '19 13:05 danielpsf

Hi everyone.

I looked into implementation and I came up one question to myself. I consider that Find should find the first index but the first is not always the nearest to begin of slice, isn't it? My question is about using binary search if slice is sorted.

I might be wrong, but even if I'm wrong you also could find index by binary search and move to left for the first.

zhiburt avatar May 13 '19 14:05 zhiburt

@zhiburt: First, Index, IndexOf, etc in my experience means the lowest index for a match. The easiest way to do this is to check from 0th index and up.

Binary search would only be meaningful for sorted slices as you say, which is rarely the case, and so it doesn’t make sense to add the IsSorted overhead.

One other thing worth mentioning is that a binary search will also have to be aware of duplicate values to ensure that it always traverses to the lowest index on a match. It’s easiest and the most general case to just brute-force it.

@danielpsf: I’m totally fine with either.

elliotchance avatar May 13 '19 22:05 elliotchance

FindFirst and FindLas really do sound like they would return the item if it is found. This sounds much more like IndexOf.

DylanMeeus avatar May 17 '19 09:05 DylanMeeus

@DylanMeeus, it makes sense, although Find already does what you said so it would be kinda weird to move forward this way.

Now that FindFirstUsing was already released with #140 (v1.27.0) I don't know if we could take it back and rename it to FindIndexUsing or FindFirstIndexUsing, like on loadash, right @elliotchance?

  • Reference: https://lodash.com/docs/4.17.11#findIndex

I'm still working on FindFirst, FindLast and FindLastUsing(expect PRs to arrive next week).

danielpsf avatar May 17 '19 19:05 danielpsf

I know using "Index" in the name is common in other languages but that's really not necessary here because I would rather be explicit about the direction. The prototypes are:

func FindFirst(ElementType) int
func FindFirstUsing(fn(ElementType) bool) int
func FindLast(ElementType) int
func FindLastUsing(fn(ElementType) bool) int

Furthermore, there could also be:

func FindAll(ElementType) []int
func FindAllUsing(fn(ElementType) bool) []int

In my opinion, it's easier and more understandable to be consistent with the first word. "Find" means we are talking about returning indexes. If we wanted to return another type, such as all elements that might match we use a different prefix, like Filter, Match, etc.

elliotchance avatar May 18 '19 07:05 elliotchance

Makes sense to me. :)

On Sat, May 18, 2019, 4:03 AM Elliot Chance [email protected] wrote:

I know using "Index" in the name is common in other languages but that's really not necessary here because I would rather be explicit about the direction. The prototypes are:

func FindFirst(ElementType) int func FindFirstUsing(fn(ElementType) bool) int func FindLast(ElementType) int func FindLastUsing(fn(ElementType) bool) int

Furthermore, there could also be:

func FindAll(ElementType) []int func FindAllUsing(fn(ElementType) bool) []int

In my opinion, it's easier and more understandable to be consistent with the first word. "Find" means we are talking about returning indexes. If we wanted to return another type, such as all elements that might match we use a different prefix, like Filter, Match, etc.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/elliotchance/pie/issues/115?email_source=notifications&email_token=AAZHOZ3KCIUBMKKJKT26U6DPV6S5RA5CNFSM4HLWIMCKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVWJDXI#issuecomment-493654493, or mute the thread https://github.com/notifications/unsubscribe-auth/AAZHOZ3OAFV5QJMSETHIV2LPV6S5RANCNFSM4HLWIMCA .

danielpsf avatar May 18 '19 12:05 danielpsf