FAQ
http://play.golang.org/p/3LB6C9LMVv


So I have the following code:

// ByTwoIndex sorts by two indices.
func ByTwoIndex(rows [][]string, idx1, idx2 int) [][]string {
idxFunc1 := func(row1, row2 *[]string) bool {
return (*row1)[idx1] < (*row2)[idx1]
}
idxFunc2 := func(row1, row2 *[]string) bool {
return (*row1)[idx2] < (*row2)[idx2]
}
by(rows, idxFunc1, idxFunc2).Sort(rows)
return rows
}

// ByTwoIndex sorts by multiple indices.
func ByMultiIndex(rows [][]string, indices ...int) [][]string {
funcSlice := []lessFunc{}
for _, idx := range indices {
idxFunc := func(row1, row2 *[]string) bool {
return (*row1)[idx] < (*row2)[idx]
}
funcSlice = append(funcSlice, idxFunc)
}
by(rows, funcSlice...).Sort(rows)
// by(rows, funcSlice[0], funcSlice[1]).Sort(rows)
// sort.Sort(by(rows, funcSlice...))
return rows
}


ByTwoIndex's results are what I expect from ByMultiIndex but for some
reason, it gets sorted by the last lessFunc in the function slices.

Can anybody help me understand what I am doing wrong in ByMultiIndex?

Thanks in advance!

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Ojucie at Feb 14, 2015 at 10:21 am
    Fixed for you. Please see makeLessFunc.

    http://play.golang.org/p/xUgI2s5cIV

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gyu-Ho Lee at Feb 14, 2015 at 10:27 am
    Thanks, it works as I expect. But I still want to learn what I was doing
    wrong:

    idxFunc := makeLessFunc(idx)

    idxFunc := func(row1, row2 *[]string) bool {
    return (*row1)[idx] < (*row2)[idx]
    }

    Both looks the same.

    Is it because the function gets added as a pointer?
    Can anybody explain what I was doing wrong in the first playground?

    Thanks
    On Saturday, February 14, 2015 at 2:21:26 AM UTC-8, oju...@gmail.com wrote:

    Fixed for you. Please see makeLessFunc.

    http://play.golang.org/p/xUgI2s5cIV


    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Kevin Gillette at Feb 14, 2015 at 11:06 am
    An alternative solution: http://play.golang.org/p/_XpatCUVCQ

    The only thing that changed is that I added line 40. The issue was that the
    `idx` declaration on line 39 is not internal to the loop body, but rather
    shared between iterations. Due to this, in your original code, all the
    functions will operate on the same closure value, which is whatever was set
    on the last iteration.

    The first responder solved this issue by passing the value of idx to a
    function which generated the same function (but this time with a unique
    closure).

    The alternative solution presented above uses `idx := idx` to declare a new
    variable scoped to the loop body itself. In that assignment, the
    right-hand-side idx refers to the one defined on line 39, and the
    left-hand-side idx is defined *after* the right-hand-side is evaluated, so
    it all works.

    See http://golang.org/doc/faq#closures_and_goroutines for a more detailed
    explanation. Even though you're not using goroutines for this, since you're
    saving closure functions for later execution, the effect is the same.
    On Saturday, February 14, 2015 at 3:27:38 AM UTC-7, Gyu-Ho Lee wrote:

    Thanks, it works as I expect. But I still want to learn what I was doing
    wrong:

    idxFunc := makeLessFunc(idx)

    idxFunc := func(row1, row2 *[]string) bool {
    return (*row1)[idx] < (*row2)[idx]
    }

    Both looks the same.

    Is it because the function gets added as a pointer?
    Can anybody explain what I was doing wrong in the first playground?

    Thanks

    On Saturday, February 14, 2015 at 2:21:26 AM UTC-8, oju...@gmail.com
    wrote:
    Fixed for you. Please see makeLessFunc.

    http://play.golang.org/p/xUgI2s5cIV
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ojucie at Feb 14, 2015 at 11:11 am
    I liked your solution, Kevin. Simpler and nicer than mine.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Kevin Gillette at Feb 14, 2015 at 11:38 am
    Many might consider it less clear than factoring out a function as you did,
    and the scoping semantics of the `i := i` approach are uncommon among other
    imperative languages; I was just using it to explain the observed behavior.
    On Saturday, February 14, 2015 at 4:11:19 AM UTC-7, oju...@gmail.com wrote:

    I liked your solution, Kevin. Simpler and nicer than mine.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gyu-Ho Lee at Feb 14, 2015 at 11:32 am
    It's really great to learn this. I wasn't paying attention to the closure
    and its execution time.
    Thanks a lot!
    On Saturday, February 14, 2015 at 3:05:56 AM UTC-8, Kevin Gillette wrote:

    An alternative solution: http://play.golang.org/p/_XpatCUVCQ

    The only thing that changed is that I added line 40. The issue was that
    the `idx` declaration on line 39 is not internal to the loop body, but
    rather shared between iterations. Due to this, in your original code, all
    the functions will operate on the same closure value, which is whatever was
    set on the last iteration.

    The first responder solved this issue by passing the value of idx to a
    function which generated the same function (but this time with a unique
    closure).

    The alternative solution presented above uses `idx := idx` to declare a
    new variable scoped to the loop body itself. In that assignment, the
    right-hand-side idx refers to the one defined on line 39, and the
    left-hand-side idx is defined *after* the right-hand-side is evaluated,
    so it all works.

    See http://golang.org/doc/faq#closures_and_goroutines for a more detailed
    explanation. Even though you're not using goroutines for this, since you're
    saving closure functions for later execution, the effect is the same.
    On Saturday, February 14, 2015 at 3:27:38 AM UTC-7, Gyu-Ho Lee wrote:

    Thanks, it works as I expect. But I still want to learn what I was doing
    wrong:

    idxFunc := makeLessFunc(idx)

    idxFunc := func(row1, row2 *[]string) bool {
    return (*row1)[idx] < (*row2)[idx]
    }

    Both looks the same.

    Is it because the function gets added as a pointer?
    Can anybody explain what I was doing wrong in the first playground?

    Thanks

    On Saturday, February 14, 2015 at 2:21:26 AM UTC-8, oju...@gmail.com
    wrote:
    Fixed for you. Please see makeLessFunc.

    http://play.golang.org/p/xUgI2s5cIV
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ojucie at Feb 14, 2015 at 11:06 am

    On Saturday, February 14, 2015 at 8:27:38 AM UTC-2, Gyu-Ho Lee wrote:
    I still want to learn what I was doing wrong
    You did nothing wrong, Lee. Every programming language has it's share of
    idiosyncrasies, including our beloved Go.

    There are two distinct moments in time when you deal with your Less
    functions. The first is the moment you create it and the second is the
    moment the function gets called. What value do you need for idx? Do you
    need the value it had when the function was created or you need the value
    idx currently have when the function gets called? You decide. The default
    behavior is the last, but in your case, what you wanted was the first.

    What did I do to solve the problem? I created a copy of idx at the stack,
    so that the Less func would refer to my copy, with the correct value, and
    not to the original idx, that changes over time. You could obtain exactly
    the same effect without creating a separated function, but I prefer to
    avoid clutter.

    For a clearer example, see this:
    http://play.golang.org/p/NxaPX7T-80

    as opposed to this:
    http://play.golang.org/p/wFo9JdOLs0


    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Gyu-Ho Lee at Feb 14, 2015 at 11:34 am
    Thank you!
    On Saturday, February 14, 2015 at 3:06:32 AM UTC-8, oju...@gmail.com wrote:
    On Saturday, February 14, 2015 at 8:27:38 AM UTC-2, Gyu-Ho Lee wrote:

    I still want to learn what I was doing wrong
    You did nothing wrong, Lee. Every programming language has it's share of
    idiosyncrasies, including our beloved Go.

    There are two distinct moments in time when you deal with your Less
    functions. The first is the moment you create it and the second is the
    moment the function gets called. What value do you need for idx? Do you
    need the value it had when the function was created or you need the value
    idx currently have when the function gets called? You decide. The default
    behavior is the last, but in your case, what you wanted was the first.

    What did I do to solve the problem? I created a copy of idx at the stack,
    so that the Less func would refer to my copy, with the correct value, and
    not to the original idx, that changes over time. You could obtain exactly
    the same effect without creating a separated function, but I prefer to
    avoid clutter.

    For a clearer example, see this:
    http://play.golang.org/p/NxaPX7T-80

    as opposed to this:
    http://play.golang.org/p/wFo9JdOLs0

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedFeb 14, '15 at 8:58a
activeFeb 14, '15 at 11:38a
posts9
users3
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase