Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #30271 > unrolled thread

duplicator an array

Started byJRough <janis.rough@gmail.com>
First post2016-04-13 18:27 -0700
Last post2017-05-03 01:33 -0700
Articles 11 — 7 participants

Back to article view | Back to comp.lang.javascript


Contents

  duplicator an array JRough <janis.rough@gmail.com> - 2016-04-13 18:27 -0700
    Re: duplicator an array Aleksandro <aleksandro@gmx.com> - 2016-04-14 01:00 -0300
      Re: duplicator an array JRough <janis.rough@gmail.com> - 2016-04-14 09:53 -0700
      Re: duplicator an array "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-04-14 19:41 +0200
        Re: duplicator an array Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-14 22:09 +0200
          Re: duplicator an array Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-14 22:23 +0200
      Re: duplicator an array Stefan Weiss <krewecherl@gmail.com> - 2016-04-16 14:27 +0200
        Re: duplicator an array Joao Rodrigues <jr@none.com> - 2016-04-16 12:01 -0300
          Re: duplicator an array Joao Rodrigues <jr@none.com> - 2016-04-16 13:43 -0300
        Re: duplicator an array Aleksandro <aleksandro@gmx.com> - 2016-04-16 14:13 -0300
    Re: duplicator an array bharat.bandgar009@gmail.com - 2017-05-03 01:33 -0700

#30271 — duplicator an array

FromJRough <janis.rough@gmail.com>
Date2016-04-13 18:27 -0700
Subjectduplicator an array
Message-ID<ea578169-9d58-4249-91b4-e0cbad5a6fd8@googlegroups.com>
I have one question for you.
The problem is to create a duplicator function like below.  To make this one work:
[1,2,3,4,5].duplicator();
------------------------
Okay, first thing i did was just get it to work in a regular function.  I think this works because I saw the duplcation of res in Firebug.  
var arr =[1,2,3,4,5];
function duplicator(arr){
    return  arr.concat(arr.slice(0));
}
var res = duplicator(arr);
console.log(res.toString());
The only problem with this one is it doesn't output the string in the console.log.
Do you know why?

---------------------
Okay, supposing the above works then I thought I would make an anonymous function in the duplicator method.  This would make it work the way the problem was first outlined above.  The only problem is how do I capture the value of the two arrays?


I guess you would do something like Array.prototype.duplicator = (function (){
    return  this.concat(arr.slice(0));
})()

[toc] | [next] | [standalone]


#30272

FromAleksandro <aleksandro@gmx.com>
Date2016-04-14 01:00 -0300
Message-ID<nen4e4$ggn$1@dont-email.me>
In reply to#30271
On 13/04/16 22:27, JRough wrote:
> 
> I have one question for you.
> The problem is to create a duplicator function like below.  To make this one work:
> [1,2,3,4,5].duplicator();
> ------------------------
> Okay, first thing i did was just get it to work in a regular function.  I think this works because I saw the duplcation of res in Firebug.  
> var arr =[1,2,3,4,5];
> function duplicator(arr){
>     return  arr.concat(arr.slice(0));
> }
> var res = duplicator(arr);
> console.log(res.toString());
> The only problem with this one is it doesn't output the string in the console.log.
> Do you know why?

It works perfectly for me.

> Okay, supposing the above works then I thought I would make an anonymous function in the duplicator method.  This would make it work the way the problem was first outlined above.  The only problem is how do I capture the value of the two arrays?
> 
> 
> I guess you would do something like Array.prototype.duplicator = (function (){
>     return  this.concat(arr.slice(0));
> })()

Try:

Array.prototype.duplicate = function ()
{
	this.push.apply(this, this.slice(0))
}

[toc] | [prev] | [next] | [standalone]


#30276

FromJRough <janis.rough@gmail.com>
Date2016-04-14 09:53 -0700
Message-ID<5f64116c-3f44-4eb6-b178-160beb37efaa@googlegroups.com>
In reply to#30272
On Wednesday, April 13, 2016 at 9:00:18 PM UTC-7, Aleksandro wrote:
> On 13/04/16 22:27, JRough wrote:
> > 
> > I have one question for you.
> > The problem is to create a duplicator function like below.  To make this one work:
> > [1,2,3,4,5].duplicator();
> > ------------------------
> > Okay, first thing i did was just get it to work in a regular function.  I think this works because I saw the duplcation of res in Firebug.  
> > var arr =[1,2,3,4,5];
> > function duplicator(arr){
> >     return  arr.concat(arr.slice(0));
> > }
> > var res = duplicator(arr);
> > console.log(res.toString());
> > The only problem with this one is it doesn't output the string in the console.log.
> > Do you know why?
> 
> It works perfectly for me.

 I can't see it in firebug scratchpad console.log I'll try it in chrome tnx
> 
> > Okay, supposing the above works then I thought I would make an anonymous function in the duplicator method.  This would make it work the way the problem was first outlined above.  The only problem is how do I capture the value of the two arrays?
> > 
> > 
> > I guess you would do something like Array.prototype.duplicator = (function (){
> >     return  this.concat(arr.slice(0));
> > })()
> 
> Try:
> 
> Array.prototype.duplicate = function ()
> {
> 	this.push.apply(this, this.slice(0))
> }

tnx again

[toc] | [prev] | [next] | [standalone]


#30277

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2016-04-14 19:41 +0200
Message-ID<neokoi$6k3$1@solani.org>
In reply to#30272
On 14.04.2016 at 06:00, Aleksandro wrote:

> On 13/04/16 22:27, JRough wrote:
>
>> Okay, supposing the above works then I thought I would make an anonymous function in the duplicator method.  This would make it work the way the problem was first outlined above.  The only problem is how do I capture the value of the two arrays?
>>
>>
>> I guess you would do something like Array.prototype.duplicator = (function (){
>>     return  this.concat(arr.slice(0));
>> })()
> 
> Try:
> 
> Array.prototype.duplicate = function ()
> {
> 	this.push.apply(this, this.slice(0))
> }


The usual caveats wrt. augmenting built-in objects apply, though, see
e.g.
<http://peter.michaux.ca/articles/javascript-the-good-parts-built-in-object-augmentation-and-namespacing>.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#30278

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-04-14 22:09 +0200
Message-ID<1593194.mKTEO0Afz8@PointedEars.de>
In reply to#30277
Christoph M. Becker wrote:

> On 14.04.2016 at 06:00, Aleksandro wrote:
>> On 13/04/16 22:27, JRough wrote:
>>> Okay, supposing the above works then I thought I would make an anonymous
>>> function in the duplicator method.  This would make it work the way the
>>> problem was first outlined above.  The only problem is how do I capture
>>> the value of the two arrays?
>>>
>>>
>>> I guess you would do something like Array.prototype.duplicator =
>>> (function (){
>>>     return  this.concat(arr.slice(0));
>>> })()
>> 
>> Try:
>> 
>> Array.prototype.duplicate = function ()
>> {
>> this.push.apply(this, this.slice(0))
>> }
> 
> 
> The usual caveats wrt. augmenting built-in objects apply, though, see
> e.g.
> <http://peter.michaux.ca/articles/javascript-the-good-parts-built-in-object-augmentation-and-namespacing>.

It should be noted that the referred article is *old*; it is dated 
2008-06-18.

We now have String.prototype.trim(), and we have .toJSON() as a hook for 
JSON.stringify() in the language standard (ES 2015, § 24.3.2, step 12), and 
it is implemented.  So it would seem that either Douglas Crockford was 
prophetic or, more likely, that his were good examples that later made it 
into the standard.  JFTR, String.prototype.trim() has been in the FAQ for 
quite a while (currently in § 8.1), and I have written toJSON() methods.

Also, one important reason for not augmenting the object referred to by 
Array.prototype, and by extension any prototype, has disappeared: we have 
standard property descriptors since ECMAScript Edition 5/5.1 
(2009-12/2011-06) so that user-defined properties need no longer be 
enumerable and need not mess up for-in iteration (useful for sparse arrays 
if order is irrelevant):

  try
  {
    Object.defineProperty(Array.prototype, "duplicate", {
      value: function () {
        return this.concat(this.slice());
      },

      /* optional; the default for each attribute is “false” */
      configurable: true,
      enumerable: false,
      writable: true
    });
  }
  catch
  {
    console.warn("Array.prototype.duplicate cannot be (re)configured.");
  }

In this case, however, there is little benefit of calling the method instead 
of inlining it with a.concat(a.slice()) [the 0 argument is optional as that 
is the implicit default (ES 2015, § 22.1.3.22, step 5)].

Also note that a.duplicate() as defined above does nothing of consequence; 
in order for it to duplicate the array items in the desired way it would 
have to define array items explicitly or its return value would need to be 
assigned to something.

In any case, it is possible to safely augment built-in prototype objects if 
you limit the scope of the change:

(function () {
  var arrayDuplicate = Array.prototype.duplicate;

  Array.prototype.duplicate = function () {
    return this.concat(this.slice());
  };

  /* do something */

  Array.prototype.duplicate = arrayDuplicate;
}());

This is safe only if there are no concurrent threads in the same global 
context as all share the same “Array” object and one of them might rely on a 
different implementation.  DNS-based namespaces, as suggested in the 
article, might be a solution to that; but all parties involved have to agree 
to that for it to work reliably.

Otherwise the only safe approach is to augment the instance instead of its 
prototype:

(function () {
  var a = [1, 2, 3];

  a.duplicate = function () {
    return this.concat(this.slice());
  };

  // …

  /* [1, 2, 3, 1, 2, 3] */
  a = a.duplicate();

  // …
}());

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#30279

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-04-14 22:23 +0200
Message-ID<4431777.cbmzjsbQN4@PointedEars.de>
In reply to#30278
Thomas 'Ingrid' Lahn wrote:

>   try
>   {
>     Object.defineProperty(Array.prototype, "duplicate", {
>       value: function () {
>         return this.concat(this.slice());
>       },
> 
>       /* optional; the default for each attribute is “false” */
>       configurable: true,
>       enumerable: false,
>       writable: true
>     });
>   }
>   catch
 .--------^
 :
(e)

>   {
>     console.warn("Array.prototype.duplicate cannot be (re)configured.");
>   }
> 
> […]
> Otherwise the only safe approach is to augment the instance instead of its
> prototype:
> 
> (function () {
>   var a = [1, 2, 3];
> 
>   a.duplicate = function () {
>     return this.concat(this.slice());
>   };

Or like above.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#30283

FromStefan Weiss <krewecherl@gmail.com>
Date2016-04-16 14:27 +0200
Message-ID<netb2m$42n$1@news.albasani.net>
In reply to#30272
Aleksandro wrote:
> On 13/04/16 22:27, JRough wrote:
>> var arr =[1,2,3,4,5];
>> function duplicator(arr){
>>     return  arr.concat(arr.slice(0));
>> }
>> var res = duplicator(arr);

...

> Try:
> 
> Array.prototype.duplicate = function ()
> {
> 	this.push.apply(this, this.slice(0))
> }

Note that this is not equivalent to OP's function.

1) push() modifies the original array, concat() does not.

2) It handles sparse arrays badly:

    "use strict";

    let a = [0,,,,4],
        b = a.slice(0);

    dir(a, "a");
    dir(b, "b");
    dir(a.concat(b), "concat()");
    a.push.apply(a, b);
    dir(a, "push() applied");

    function dir (arr, label)
    {
        console.log(label + ":");
        for (let i in arr) console.log(`  [${i}] = ${arr[i]}`);
    }

Output:

    a:
      [0] = 0
      [4] = 4
    b:
      [0] = 0
      [4] = 4
    concat():
      [0] = 0
      [4] = 4
      [5] = 0
      [9] = 4
    push() applied:
      [0] = 0
      [4] = 4
      [5] = 0
      [6] = undefined
      [7] = undefined
      [8] = undefined
      [9] = 4

This is because apply() fills in `undefined` for missing parameters.


By the way, ES2015 introduced the spread operator `...`.
With this operator, you can also write

    this.push(...this.slice(0))

instead of

    this.push.apply(this, this.slice(0))


-- stefan

[toc] | [prev] | [next] | [standalone]


#30284

FromJoao Rodrigues <jr@none.com>
Date2016-04-16 12:01 -0300
Message-ID<netk4f$vsl$1@gioia.aioe.org>
In reply to#30283
On 16/04/2016 09:27, Stefan Weiss wrote:

>
> By the way, ES2015 introduced the spread operator `...`.
> With this operator, you can also write
>
>     this.push(...this.slice(0))
>
> instead of
>
>     this.push.apply(this, this.slice(0))
>

Yeah, the spread operator makes life a lot easier: [1]:

     let arr1 = ['a', 'b'];
     let arr2 = ['c'];
     let arr3 = ['d', 'e'];

     console.log([...arr1, ...arr2, ...arr3]);
     // [ 'a', 'b', 'c', 'd', 'e' ]

[1] <http://www.2ality.com/2015/08/getting-started-es6.html>

Cheers,
Joao Rodrigues

[toc] | [prev] | [next] | [standalone]


#30285

FromJoao Rodrigues <jr@none.com>
Date2016-04-16 13:43 -0300
Message-ID<netq3l$1ao7$1@gioia.aioe.org>
In reply to#30284
On 16/04/2016 12:01, Joao Rodrigues wrote:
> On 16/04/2016 09:27, Stefan Weiss wrote:
>
>>
>> By the way, ES2015 introduced the spread operator `...`.
>> With this operator, you can also write
>>
>>     this.push(...this.slice(0))
>>
>> instead of
>>
>>     this.push.apply(this, this.slice(0))
>>
>
> Yeah, the spread operator makes life a lot easier: [1]:
>
>     let arr1 = ['a', 'b'];
>     let arr2 = ['c'];
>     let arr3 = ['d', 'e'];
>
>     console.log([...arr1, ...arr2, ...arr3]);
>     // [ 'a', 'b', 'c', 'd', 'e' ]
>
> [1] <http://www.2ality.com/2015/08/getting-started-es6.html>
>

As an exercise, the OP's code might be rewritten in ES6 to:

Array.prototype.duplicator = function () {
   return [...this, ...this];
};
[1,2,3,4,5].duplicator();
// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

Tested with latest versions of MS Edge, Chrome and FF.

--
Joao Rodrigues

[toc] | [prev] | [next] | [standalone]


#30286

FromAleksandro <aleksandro@gmx.com>
Date2016-04-16 14:13 -0300
Message-ID<netrli$9dr$1@dont-email.me>
In reply to#30283
On 16/04/16 09:27, Stefan Weiss wrote:
> Aleksandro wrote:
>> On 13/04/16 22:27, JRough wrote:
>>> var arr =[1,2,3,4,5];
>>> function duplicator(arr){
>>>     return  arr.concat(arr.slice(0));
>>> }
>>> var res = duplicator(arr);
> 
> ...
> 
>> Try:
>>
>> Array.prototype.duplicate = function ()
>> {
>> 	this.push.apply(this, this.slice(0))
>> }
> 
> Note that this is not equivalent to OP's function.
> 
> 1) push() modifies the original array, concat() does not.
> 
> 2) It handles sparse arrays badly:
> 
>     "use strict";
> 
>     let a = [0,,,,4],
>         b = a.slice(0);
> 
>     dir(a, "a");
>     dir(b, "b");
>     dir(a.concat(b), "concat()");
>     a.push.apply(a, b);
>     dir(a, "push() applied");
> 
>     function dir (arr, label)
>     {
>         console.log(label + ":");
>         for (let i in arr) console.log(`  [${i}] = ${arr[i]}`);
>     }
> 
> Output:
> 
>     a:
>       [0] = 0
>       [4] = 4
>     b:
>       [0] = 0
>       [4] = 4
>     concat():
>       [0] = 0
>       [4] = 4
>       [5] = 0
>       [9] = 4
>     push() applied:
>       [0] = 0
>       [4] = 4
>       [5] = 0
>       [6] = undefined
>       [7] = undefined
>       [8] = undefined
>       [9] = 4
> 
> This is because apply() fills in `undefined` for missing parameters.
> 
> 
> By the way, ES2015 introduced the spread operator `...`.
> With this operator, you can also write
> 
>     this.push(...this.slice(0))
> 
> instead of
> 
>     this.push.apply(this, this.slice(0))
> 
> 
> -- stefan

It could have been what the OP intended though.

[toc] | [prev] | [next] | [standalone]


#33172

Frombharat.bandgar009@gmail.com
Date2017-05-03 01:33 -0700
Message-ID<066f8925-57a8-4cad-94cd-d31599c1b659@googlegroups.com>
In reply to#30271
Array.prototype.duplicator = function(){
  return this.concat(this);  
}

[1,2,3,4,5].duplicator(); // [1,2,3,4,5,1,2,3,4,5]
            

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web