prelude-ls icon indicating copy to clipboard operation
prelude-ls copied to clipboard

jQuery.extend(true, ...) function in prelude-ls

Open ceremcem opened this issue 9 years ago • 10 comments

As I mistakenly opened the issue in https://github.com/gkz/LiveScript/issues/780 , wouldn't it be useful to have this function in prelude-ls?

ceremcem avatar Sep 24 '15 19:09 ceremcem

Following function (taken from stackoverflow) does what jQuery.extend(true, ...) does:

export function merge obj1, obj2           
  for p of obj2
    try
      if obj2[p].constructor ~= Object 
        obj1[p] = obj1[p] `merge` obj2[p]
      else 
        obj1[p] = obj2[p]
    catch 
      obj1[p] = obj2[p]
  obj1

Example for merge:

a= 
  a: 1
  b: 2
  c: 
    ca: 1
    cb: 2

b= 
  c: 
    cb: 5

a `merge` b  # => {a: 1, b: 2, c: {ca: 1, cb:5}}

in order to delete a key, just specify void as a value:

a= 
  a: 1
  b: 2
  c: 
    ca: 1
    cb: 2
    e:  
      k: 11

b= 
  c: 
    ca: void

a `merge` b # => {"a":1,"b":2,"c":{"cb":2,"e":{"k":11}}}

ceremcem avatar Apr 30 '16 08:04 ceremcem

Here is my version that doesn't mutate the first argument and takes an infinite amount of input objects.

# merge :: object -> ...object -> object
export function merge (...sources)
    res = {}
    for src in sources
        for own key, val of src
            res[key] = val
    res

any reason for the try catch other than circular references?

igl avatar May 02 '16 07:05 igl

@igl Examples are giving different results. Your version behaves like a <<< b (merges/overwrites only the root elemets).

ceremcem avatar May 02 '16 07:05 ceremcem

Here is the modified version of yours:

export function merge (obj1, ...sources)
  for obj2 in sources
    for p of obj2
      try
        throw if obj2[p]@@ !~= Object
        obj1[p] = obj1[p] `merge` obj2[p]
      catch
        obj1[p] = obj2[p]
  obj1

...which is useful when forcibly overriding a key:


a= 
  a: 1
  b: 2
  c: 
    ca: 1
    cb: 2
  d: 
    da: 1
    db: 2
    dc: 3

b= 
  c: 
    cb: 5
  d:  # you want this branch to override, not to merge
    da: 5

merge a, {d: void}, b

Try/catch block is mandatory when you pass an object like {x: void}.

ceremcem avatar May 02 '16 08:05 ceremcem

big -1 on checking @@.

vendethiel avatar May 02 '16 08:05 vendethiel

@vendethiel because of checking style of @@ or checking @@ in the first place?

ceremcem avatar May 02 '16 08:05 ceremcem

No, I mean comparing @@ to Object is bad.

vendethiel avatar May 02 '16 09:05 vendethiel

Is the following ok:

function merge (obj1, ...sources)
  for obj2 in sources
    for p of obj2
      try
        throw if obj2[p] not instanceof Object
        obj1[p] = obj1[p] `merge` obj2[p]
      catch
        obj1[p] = obj2[p]
  obj1

ceremcem avatar May 02 '16 12:05 ceremcem

why do you want such a check?

vendethiel avatar May 02 '16 12:05 vendethiel

this code doesn't belong to me, it's from stackoverflow and it just worked.

edit: any tips for the downvotes? :)

edit2: https://github.com/ceremcem/merge-ls

edit3: https://github.com/aktos-io/aktos-scada2/blob/master/src/lib/aea/merge.ls

ceremcem avatar May 02 '16 12:05 ceremcem