Some great comments, thank you very much, John. You are very helpful, as always!
 
I have settled on the following code:
 
```
: path-assoc ( seq -- assoc )
    [ [ path>> ] keep ] H{ } map>assoc ;
 
: assoc-3diff ( left-assoc right-assoc -- left-only both right-only )
    [ assoc-diff ] [ assoc-intersect ] [ swap assoc-diff ] 2tri ;
 
: paths-partition ( old new -- deleted remained added )
    [ path-assoc ] bi@ assoc-3diff ;
```
 
This satisfies the requirement of only having to create an assoc once for each input sequence.
The name `assoc-3diff` is to avoid clashing with the existing `assoc-partition`.
 
03.08.2016, 03:20, "John Benediktsson" <mrj...@gmail.com>:
Well, some comments:
 
1) You don't have to ``[ ... 2array ] map >hashtable``, you can map into a hashtable directly using ``map>assoc``:
 
: paths-diff ( old new -- seq )
    [ [ [ path>> ] keep ] H{ } map>assoc ] bi@ assoc-diff values ;
 
2) If you want to only create the temporary assoc once, you can do something like this:
 
: path-assoc ( seq -- assoc )
    [ [ path>> ] keep ] H{ } map>assoc ;
 
: paths-changed ( old new -- deleted added )
   [ path-assoc ] bi@ [ assoc-diff ] [ swap assoc-diff ] 2bi [ values ] bi@ ;
 
3) If your tuples can be compared for equality by all slots, not just their paths, you could just use set operations:
 
: paths-changed ( old new -- deleted added )
    [ diff ] [ swap diff ] 2bi ;
 
4) Are you thinking you want/need an efficient way to do something like this?
 
: set-partition ( set1 set2 -- left-diff intersection right-diff )
    [ diff ] [ intersect ] [ swap diff ] 2tri ;
 
: assoc-partition ( assoc1 assoc2 -- left-diff intersection right-diff )
    [ assoc-diff ] [ assoc-intersect ] [ swap assoc-diff ] 2tri ;
 
5) This is maybe marginally more efficient in some cases (if the inputs are sequences), and probably less efficient in others (if the inputs are hash-sets).  I would guess it's not worth the trouble, versus using the ``sets`` or ``assocs`` vocabulary words:
 
:: set-partition ( set1 set2 -- left-diff intersection right-diff )
    HS{ } clone :> left-diff
    HS{ } clone :> intersection
    HS{ } clone :> right-diff
 
    set1 set2 sequence/tester
    '[ dup @ intersection left-diff ? adjoin ] each
 
    set2 set1 sequence/tester
    '[ dup @ intersection right-diff ? adjoin ] each
 
    left-diff intersection right-diff ;
 
I guess my general recommendation would be to keep the code as simple as possible.
 
Best,
John.
 
 
 
On Tue, Aug 2, 2016 at 3:07 PM, Alexander Ilin <ajs...@yandex.ru> wrote:
Hello!

  I have a tuple that contains a file path in its `path` slot. And I have two sequences of such tuples, representing two states of a disk.

  I want to know which files were added, which were removed, and which remained between the two states. Only paths are to be considered by the analysis, but the resulting sequences should consist of the source tuples, not merely path strings.

  Here's what I came up with:

```
: paths-diff ( old new -- seq )
    [ [ dup path>> swap 2array ] map >hashtable ] bi@ assoc-diff values ;

: paths-deleted ( old new -- seq ) paths-diff ;
: paths-added ( old new -- seq ) swap paths-diff ;
```

  Then I thought that creating the assocs every time I need to diff is perhaps not very bright.

  Is it possible to partition an assoc in a way similar to the way the `partition` word splits a seq into trueseq and falseseq?
  Do we have a word to partition a set or an assoc three-way: left-diff, intersection and right-diff?

---=====---
 Александр

------------------------------------------------------------------------------
_______________________________________________
Factor-talk mailing list
Factor-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/factor-talk
,

------------------------------------------------------------------------------

,

_______________________________________________
Factor-talk mailing list
Factor-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/factor-talk

 
 
---=====---
Александр
 
------------------------------------------------------------------------------
_______________________________________________
Factor-talk mailing list
Factor-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to