Added powerful Array functions. #303

Closed
wants to merge 1,241 commits into
from

Conversation

Projects
None yet
Contributor

kevincox commented Apr 4, 2013

I felt the array functions could use a bit more. The commit messages are below.

Added Array.replace().

Array.replace is a convenience function around Array.removeAt() and Array.add(). There is also Array.replaced() that returns a new Array where the values have been replaced.

Array.replace() can also be called with no elements for a pythonic feel.

Added Array.cut().

Array.cut is a complex method for creating a new string from pieces of an old string. It supports beginning, end, step and count parameters allowing precise control of the result. For convenience it wraps indecies by default but that can be disabled for more complex queries. Reverse iteration is supported and many optimization shortcuts are taken, including falling back to a single slice() call on simple queries.

andrewplummer and others added some commits Dec 31, 2011

@andrewplummer andrewplummer fixing zh-CN date dumbness 01d4acf
@andrewplummer andrewplummer updating changelog c13425d
@andrewplummer andrewplummer performance optimization for classname check d5817de
@andrewplummer andrewplummer making test equality helper match the spec. cleaning up matchByValue and
incluing arguments objects too
7fa507b
@andrewplummer andrewplummer debounce should have its timers on the debounced function 8687730
@andrewplummer andrewplummer build for last commit 186f4da
@andrewplummer andrewplummer mostly refactoring of UTC date handling.. added createUTC and utc and
deprecated toUTC
441fa0f
@demonkoryu demonkoryu Custom build: produce development version with only required modules.…
… Fixes SugarJS #189
5791e9f
@andrewplummer andrewplummer Merge pull request #190 from demonkoryu/build-modular-development-dist
Custom build: produce development version with only required modules. Fixes SugarJS #190
329cf11
@andrewplummer andrewplummer more for #190 a58463c
@andrewplummer andrewplummer utc changes 755c1f1
@andrewplummer andrewplummer fixing failing tests 5d16dab
@andrewplummer andrewplummer getWeek should not change the date (Issue 192) 19dffd9
@andrewplummer andrewplummer updates for utc checking 348b200
@andrewplummer andrewplummer build for previous commits 61fb6a3
@andrewplummer andrewplummer Merge branch 'utc_refactoring' 187322c
@andrewplummer andrewplummer Merge branch 'master' into match_by_reference
Conflicts:
	release/edge/precompiled/minified/array.js
	release/edge/precompiled/minified/core.js
	release/edge/precompiled/minified/date.js
	release/edge/precompiled/minified/date_ranges.js
	release/edge/precompiled/minified/es5.js
	release/edge/precompiled/minified/function.js
	release/edge/precompiled/minified/inflections.js
	release/edge/precompiled/minified/language.js
	release/edge/precompiled/minified/number.js
	release/edge/precompiled/minified/object.js
	release/edge/precompiled/minified/regexp.js
	release/edge/precompiled/minified/string.js
	release/edge/sugar-edge-full.min.js
	release/edge/sugar-edge.min.js
	unit_tests/environments/sugar/array.js
	unit_tests/javascripts/setup.js
532a853
@andrewplummer andrewplummer fixing date range infinite loop during DST traversal 7d025a6
@andrewplummer andrewplummer build 5c45bf8
@andrewplummer andrewplummer updating changelog and finally removing toUTC e831f6a
@andrewplummer andrewplummer build 8e7c1da
@andrewplummer andrewplummer gearing up for 1.3.1 release d0fb722
@andrewplummer andrewplummer npm package bump 8c90db5
@andrewplummer andrewplummer docs tweak 2037179
@andrewplummer andrewplummer testing minified downloads 317ee39
@andrewplummer andrewplummer UTC flag not forced 84c6858
@andrewplummer andrewplummer simple vars fix 62167ec
@andrewplummer andrewplummer Function#bind does not override native implementation 5ef73d3
@andrewplummer andrewplummer updating changelog 909ead3
@andrewplummer andrewplummer moving array documentation e3b4c80
@andrewplummer andrewplummer Merge branch 'master' of github.com:andrewplummer/Sugar 087e53a
@andrewplummer andrewplummer remove buildBind be7a257
@andrewplummer andrewplummer build and skipping instanceof checks in node 66c5162
@andrewplummer andrewplummer simplifying prototype property for bind d0737aa
@andrewplummer andrewplummer build for 1.3.2 1b7de41
@andrewplummer andrewplummer npm version bump 31e3538
@andrewplummer andrewplummer docs updates adf3aad
@andrewplummer andrewplummer functions do not act as callbacks when matching functions. Version bump
to 1.3.3
26f851d
@andrewplummer andrewplummer splitting the changelog a72581b
@andrewplummer andrewplummer changing to Date.utc e38fbfe
@andrewplummer andrewplummer build for 1.3.4 1a1fdc2
@andrewplummer andrewplummer update to 1.3.4 ebdb968
@andrewplummer andrewplummer all created utc dates start out with the flag as false d41b5d8
@andrewplummer andrewplummer build 45d3b32
@andrewplummer andrewplummer more test fixes 255cf16
@andrewplummer andrewplummer Array.create issue with objects #195. e617580
@andrewplummer andrewplummer better distributed random numbers #196 4ee0cab
@jikamens jikamens Add Dutch locale 2319754
@jikamens jikamens Dutch date unit tests and improvements 72a99c4
@andrewplummer andrewplummer Merge pull request #198 from jikamens/master
Add Dutch locale
aff1db5
@andrewplummer andrewplummer adding dutch to more tests 32ac8be
@andrewplummer andrewplummer one too many 2c2d5e5
@andrewplummer andrewplummer cleanup for Array.create... converting any object primitive to be an
array if possible
561d294
@andrewplummer andrewplummer build for last 393474d
@joeyblake joeyblake fixes problem where urlencoded uri in the query string will fail. e.g…
…. ?_host=http%3A%2F%2Fwww.site.com%2Fslug%3Fin%3D%2Fuser%2Fjoeyblake
ab7635e
@andrewplummer andrewplummer adding test for equal sign in url params 8e4fa9e
@andrewplummer andrewplummer Merge pull request #202 from joeyblake/master
Fixes issue in Object.fromQueryString where urlencoded url query string breaks the result
1f540c9
@andrewplummer andrewplummer Merge branch 'master' of github.com:andrewplummer/Sugar 4ab84d8
@andrewplummer andrewplummer adding support for "1 hour later" etc (Issue #199) f1c31ee
@andrewplummer andrewplummer allowing missing support of am/pm (Issue #201) 672ac13
@andrewplummer andrewplummer Date#format with no am/pm (Issue #201) 9056903
@andrewplummer andrewplummer do not rely on Date#clone in Date#create (not testable. Issue #200) 9d720d0
@andrewplummer andrewplummer adding support for "the day after tomorrow" + time (Issue #203) 68f5904
@andrewplummer andrewplummer Chinese not parsing hours correctly (Issue #204) 63c84cd
@andrewplummer andrewplummer build for last commits 8cb07eb
@andrewplummer andrewplummer allowing date of month without month specified and also making optionals
not optional
a773b54
@andrewplummer andrewplummer renaming optionals to tokens now that they're not always optional 7f90989
@andrewplummer andrewplummer starting on Finnish and refactoring Russian to be more adaptable eeff96b
@andrewplummer andrewplummer build for last commit 8dc9d2f
@andrewplummer andrewplummer bit of refactoring to include durations e79cfe2
@andrewplummer andrewplummer russian fixes aa902e7
@andrewplummer andrewplummer build a50be3a
@saebekassebil saebekassebil Add danish locale with unit tests 519b366
@andrewplummer andrewplummer Merge pull request #208 from saebekassebil/master
Danish locale with unit tests
c443195
@saebekassebil saebekassebil Fix januari => januar 2fc69d3
@andrewplummer andrewplummer Merge pull request #209 from saebekassebil/master
Fix unit test failure in #208
a0c9d19
@andrewplummer andrewplummer Date.future failure fix (Issue #210) 6ae7373
@andrewplummer andrewplummer adding 1.3.5 e452f5c
@andrewplummer andrewplummer updating changelog 75892ef
@andrewplummer andrewplummer package bump eee7e90
@andrewplummer andrewplummer Object.each refactoring. 594fa0f
@andrewplummer andrewplummer build 360ef9c
@andrewplummer andrewplummer functions cannot be matched directly 0ecacfb
@andrewplummer andrewplummer build 3147b81
@andrewplummer andrewplummer more html entities (Issue #212) 7d4d5b2
@termi termi Fast String.prototype.repeat b094765
@andrewplummer andrewplummer Merge pull request #214 from termi/master
Fast String.prototype.repeat
e842268
@andrewplummer andrewplummer couple style changes and updated changelog b187958
@andrewplummer andrewplummer Merge branch 'master' of github.com:andrewplummer/Sugar 15f5b09
@andrewplummer andrewplummer bugfix for Array#sample (Issue #216) c7474e5
@andrewplummer andrewplummer build a8b02a5
Contributor

alFReD-NSH commented on c7474e5 Oct 5, 2012

I think, this change is gonna have a performance impact on large arrays.

andrewplummer and others added some commits Dec 13, 2012

@andrewplummer andrewplummer small performance improvements b54f84f
@andrewplummer andrewplummer something odd with functions that prevents bailing early d6e582f
@andrewplummer andrewplummer simple variable swap 1d5cb16
@andrewplummer andrewplummer fix for issue #252 ... Math.random does not work with parseInt 0748d6f
@andrewplummer andrewplummer Start making setWeek follow ISO8601 27e35c8
@kossnocorp kossnocorp Random refactoring of lib/core.js 04903f2
@andrewplummer andrewplummer refactoring to remove old versions from release/ f5f4b62
@andrewplummer andrewplummer removing old packages 12c1a80
@andrewplummer andrewplummer test.js runs from release/ 31dcb44
@andrewplummer andrewplummer .npmignore additions 806e288
@andrewplummer andrewplummer preserving weekday when using setWeek and fixing tests 8fb3e26
@andrewplummer andrewplummer improving docs for setWeekday 9a4643a
@andrewplummer andrewplummer changing getWeek and setWeek to getISOWeek and setISOWeek 444ff4b
@andrewplummer andrewplummer fall back to monthsFromNow when getting an adjusted date unit for the
sake of traversing across february (specifically) which is technically
not 2 full months away
61a1b36
@andrewplummer andrewplummer making a way for type checks to be accessed dynamically outside the
global context
07c4cb2
@andrewplummer andrewplummer update default test ce549b9
@andrewplummer andrewplummer build 99b4faf
@andrewplummer andrewplummer changelog update c87e573
@andrewplummer andrewplummer adding weekday to French format #249 e72f97d
@andrewplummer andrewplummer fix for conflict with Coffeescript #248 54cef32
@andrewplummer andrewplummer build for last 13f9cf6
@andrewplummer andrewplummer Merge commit '04903f2'
Conflicts:
	lib/core.js
4bb6e1a
@andrewplummer andrewplummer do not call UTCISOWeek internally 6d03561
@andrewplummer andrewplummer build 98329b0
David Hansen Fixed a problem with unescapeHTML() unescaping two levels of HTML esc…
…aping.
595d2f1
@andrewplummer andrewplummer fixing UTC quirks c2bd1b9
@andrewplummer andrewplummer build for last 6ce1063
@andrewplummer andrewplummer Merge pull request #258 from hansede/master
unescapeHTML() bug fix
2c9fe72
@andrewplummer andrewplummer build 3261bb3
@andrewplummer andrewplummer preserve date _utc flag in Object.clone #256 eddcf08
@andrewplummer andrewplummer changelog ac87ab8
@andrewplummer andrewplummer cautionlog 8c4d20d
@andrewplummer andrewplummer lazy/throttled functions now return a memoized result, allowing them to
work as a caching mechanism #247
274b83a
@andrewplummer andrewplummer refactor Function#once. A single-op memoize function is equal to
throttling forever!
72f9538
@andrewplummer andrewplummer build 8562b69
@andrewplummer andrewplummer fixing compiler issues 107c7a6
@andrewplummer andrewplummer updating year 999 tests to follow iso standard c16705d
@andrewplummer andrewplummer build f06241b
@andrewplummer andrewplummer updating versions 30279bd
@andrewplummer andrewplummer scripts update 298e5a9
@andrewplummer andrewplummer adding precompiled to ignore list 74f94d5
@andrewplummer andrewplummer updating copyright year 9b50b7e
@andrewplummer andrewplummer starting on issue #234 82ddca2
@andrewplummer andrewplummer can remove uniqueRegExpFlags now 765d72f
@andrewplummer andrewplummer hiding date tests for now for #234 b059aa0
@andrewplummer andrewplummer build b36ab62
@andrewplummer andrewplummer finalizing Object.toQueryString #234 3efb365
@andrewplummer andrewplummer build cc3cbc9
@andrewplummer andrewplummer restore toQueryString on extended e67122e
@andrewplummer andrewplummer fixing timezone offset for issue #262 337dc4d
@andrewplummer andrewplummer Merge branch 'master' of github.com:andrewplummer/Sugar 8083dce
@andrewplummer andrewplummer changelog debb202
@andrewplummer andrewplummer isToday etc. should always work regardless of locale #264 c596308
@andrewplummer andrewplummer build 3513432
@andrewplummer andrewplummer bad docs a873da1
@andrewplummer andrewplummer Merge branch 'master' of github.com:andrewplummer/Sugar 745f8ba
@andrewplummer andrewplummer removing String#namespace #265 2f146fa
@andrewplummer andrewplummer build e4c0598
@andrewplummer andrewplummer bumping versions f5fa24c
@andrewplummer andrewplummer docs aff0620
@andrewplummer andrewplummer changelog 8a8eb40
@andrewplummer andrewplummer putting namespace back in the extra/ dir 26f333a
@andrewplummer andrewplummer unused variable 836499e
@andrewplummer andrewplummer adding a fix for relative dates that come up "4 weeks" but are actually
past the month threshold
ee8111f
@andrewplummer andrewplummer renaming getAdjusted... to getRelative... c696fe1
@andrewplummer andrewplummer build 424b921
@andrewplummer andrewplummer indexOf !== -1 241bb26
@andrewplummer andrewplummer comment about padNumber & getOrdinalizedSuffix e8cb2ca
@andrewplummer andrewplummer ohrite, "hyphens" are also minus signs 2c6b810
@andrewplummer andrewplummer Base 64 encoding of Unicode strings #268 797e4ce
@andrewplummer andrewplummer build for last e4ac696
@andrewplummer andrewplummer daysUntil dealing with DST traversal #267 d6594e8
@andrewplummer andrewplummer build for last 0d15d8d
@andrewplummer andrewplummer Merge branch 'master' of github.com:andrewplummer/Sugar 789643c
@andrewplummer andrewplummer updating docs for Array#map 87e3a5c
@andrewplummer andrewplummer fixing stack split regex #271 2e14896
Farid Neshat Fix dateEqual error not showing right file in test reports
For #271
6b8bc0f
@andrewplummer andrewplummer Merge pull request #272 from alFReD-NSH/test-errors
Fix dateEqual error not showing right file in test reports
4e8d7b0
Farid Neshat Make release script return 1 with no version
This is needed for better usablity and integration with other
programs
e785f06
Farid Neshat Make release script write error to stderr 900f100
@andrewplummer andrewplummer Merge pull request #277 from alFReD-NSH/release-script
Release script
2c2c5d6
@kevincox kevincox Added Array.cut().
Array.cut is a complex meathod for creating a new string from pieces of an
old string.  It supports begining, end, step and count parameters allowing
percice control of the result.  For convienice it wraps indecies by default
but that can be disabled for more complex queries.  Reverse iteration is
supported and many optimization shortcuts are taken, including falling back to
a single slice() call on simple queries.
4c85b77
@kevincox kevincox Added Array.replace().
Array.replace is a convience function around Array.removeAt() and Array.add().
There is also Array.replaced() that returns a new Array where the values have
been replaced.

Array.replace() can also be called with no elements for a pythonic feel.
582fe71
@kevincox kevincox Fixed bug in cut()'s opimization. 7a48ed2
Owner

andrewplummer commented Apr 28, 2013

I'm going to be working on a new plugins page for Sugar. I think these methods would be perfect for it.

Contributor

milaniliev commented Sep 6, 2013

Array.replace sounds awesome. I couldn't find these on the plugin page, what happened?

In the same vein, I was suprised Array.equals does not exist. @andrewplummer: would you consider implementing this using Object.equal?

Owner

andrewplummer commented Sep 9, 2013

What plugin page are you referring to? Plugins are going to be managed by either bower or component, but hasn't happened yet.

And Array.equals is Object.equal ... it's the same concept, same thing.

Contributor

milaniliev commented Sep 9, 2013

Oh, sorry.

"I'm going to be working on a new plugins page for Sugar." <- I thought you meant http://sugarjs.com/plugins

Also, what I meant is I wanted something like [1,2,3].equals([1,2,3]) to work; I think that looks better and is less clunky than Object.equal([1,2,3], [1,2,3]).

Owner

andrewplummer commented Sep 9, 2013

  1. Whoa, sorry... that page shouldn't have even been there... it was just a prototype (all the code is still in the lib/plugins directory now anyway).. and there will no longer be a page, but instead component or bower will be leveraged for dependency reasons, so no page will exist.
  2. Ah I see that seems pretty reasonable actually. It will have to reside in the Object package, however as in the end it is comparing objects on a (potentially) deep level.
Contributor

milaniliev commented Sep 9, 2013

  1. Cool! We use bower. (Kinda.)
  2. I was proposing that you just alias [].equals(other) to Object.equal(this, other). Is that what you were thinking too? This way, the functionality does stay in the Object package, but the syntax I like exists. (Seriously, Javascript, == is object identity for Arrays, but equivalence for Strings? Why. )
Owner

andrewplummer commented Sep 9, 2013

  1. Yeah that's what I was thinking... same as Object#equals for extended objects.

I don't see the point of these implementations as they are very similar with vanilla Array methods.

Array.cut is similar to Array.slice:

[1,2,3,4].cut();  -> [1,2,3,4]
[1,2,3,4].cut(2);  -> [3,4]
[1,2,3,4].cut(-2);  -> [3,4]
[1,2,3,4].cut(1,3);  -> [2,3]

[1,2,3,4].slice();  -> [1,2,3,4]
[1,2,3,4].slice(2);  -> [3,4]
[1,2,3,4].slice(-2);  -> [3,4]
[1,2,3,4].slice(1,3);  -> [2,3]

Array.replaced is similar to Array.splice method

var a = [1,2,3,4];
a.replaced(1,2,[5,6]); -> [1,5,6,4];
a.splice(1,2,5,6); -> [1,5,6,4];

Also, I first thought Array.replace would take a value as an argument, to follow the behaviour of String.replace

[1,2,3,4].replace(1,2)  -> [2,2,3,4];
Contributor

kevincox commented Dec 7, 2013

...as they are very similar with vanilla Array methods.

Yes, they are.

Array.cut is similar to Array.slice:

Yes, it is a superset of functionality. I find I am commonly using the step ability to pick items out of an array. Being able to reverse is also useful reasonably often.

Array.replaced is similar to Array.splice method

Yes, but I find Array#splice really awkward to use. Particularly because it needs the arguments flattened.

var a = [1,2,3,4];
var b = [7,8,9];
a.splice(1,2,b);
a; //-> [1,[7,8,9],4]; // Oops.

I almost always find myself calling it like a.splice.apply(a, [2, 5].concat(b)) which is super ugly to say the least.

I also find creating a new array and returning it a lot more useful that returning the removed elements. (how often you you care what elements you remove?)

If the goal is to make a superset of an existing function, why not extend this function? Or at least use it in the implementation for performance reasons.

Also, splice returning removed elements is useful when moving items from an array to another. That's why Array.pop and Array.shift returns the removed element too. To clone the array and return a new one, a slice() call is easy enough. Deep cloning can be an issue too

Contributor

kevincox commented Dec 8, 2013

If the goal is to make a superset of an existing function, why not extend this function?

I feel like this would be confusing at best. Also they aren't exact supersets on the API level (slightly different) although that could be changed.

Or at least use it in the implementation for performance reasons.

#cut does when it can. #replace does it using two native functions but it could be changed to use Array#splice however it gets uglier (see point above).

Also, splice returning removed elements is useful when moving items from an array to another. That's why Array.pop and Array.shift returns the removed element too. To clone the array and return a new one, a slice() call is easy enough. Deep cloning can be an issue too

I'm not saying it never is. But personally I use this rarely. Also #shift and #pop are designed for getting the item. The are for stack-style usage. You could make the same argument for #splice but I find a rarely ignore their return values whereas with #splice it is the other way around.


Please realize that these are my opinions based on my use case. Feel free to decide they are not worth including. I have no problem using them in my projects without them being upstreamed. Also when the package/addon system gets implemented that may be the best place for these functions.

Yes, I agree a new package system would be great for SugarJS. With the option to select exactly what functions to add. Or a plugins page with proposed enhancements like yours. However we have to manage internal dependencies

cowwoc commented Jul 22, 2014

@andrewplummer a related feature request: We should be able to compare arrays, ignoring order. Object.equal() isn't a direct solution because it cares about order.

I agree this isn't a perfect solution but I read elsewhere you rejected the idea of adding Sets to this API so we need to push this functionality into Array instead.

Owner

andrewplummer commented Oct 26, 2015

Hi guys. I'm really sorry I've been sitting on this ticket for more than 2 years. I really appreciate all the work that @kevincox put in (he even wrote unit tests!), and I should have responded much sooner.

A lot is changing with Sugar. The plugins page still hasn't happened yet but Sugar 2.0.0 is actually addressing the publishing of plugins in a much more standardized way. The core of Sugar will be split out into its own module and the goal is for Sugar to be dead simple to extend, even without requiring any of the methods at all.

After this change has gone out I'll probably have a wiki page here listing up the different plugins available. I will try to maintain this list but of course the plugin authors will be responsible for their plugins.

As to this pull request itself, although I really appreciate the time put in, I don't think these methods are in line with the Sugar methods on their own. For cut, Sugar implements to and from with more complex index behaviors like negatives etc, which are something like cut but broken apart to smaller operations. replace is extremely similar to splice. I can respect the opinion that the native syntax is awkward, and it often is, but this is a fine line to walk and it's Sugar's hard opinion to not mask native ways of doing things unless it's a slam-dunk case (something like creating an array from an Arguments object).

But the goal of 2.0.0 is to not have my word be final. I want to make it as easily as possible to publish Sugar plugins. If these gain enough popularity and can prove themselves then they will be re-examined for putting in the library itself. It's kind of a way to objective give an answer to people saying "this would be useful".

When 2.0.0 is released I'm going to update the readme with a link to a different repo that will have plugin examples and a template of how to author, so please check back here then (I'll also probably tap you when everything's gone out).

Lastly, as to the tangential question of equals that came up, that method is now isEqual but should be otherwise identical functionally. I will consider exposing this functionality on arrays. As to the question of supporting sets, I created a new ticket to have a look at that as well #520.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment