How should I maintain a sorted array?

282 views
Skip to first unread message

moor...@gmail.com

unread,
Aug 1, 2014, 12:28:31 PM8/1/14
to polym...@googlegroups.com
Hi!

I wanna create a array sorted in increasing order, and may change value of some elements, or add/remove elements.
My solution is: Use <template repeat> and add listen to on-change event, each time I change an element will re-sort the whole array, but I am afraid that this may be slow, is there any better idea? Thanks!

Eric Bidelman

unread,
Aug 1, 2014, 1:43:17 PM8/1/14
to moor...@gmail.com, polymer-dev
The data binding system is smart in that it maintains a reference to the nodes it produces in the dom, based on the data model. Unless your items physically change location in the array, they will be left intact in the DOM. Only the minimal changes you make to the item's model will be changed in the DOM.

One thing you can do is maintain the origin array as the source of truth, and setup a parallel filtered/sorted version of the array that you template repeat over.  Filter example:

<template repeat="{{item, i in filteredList}}">

this.filteredListed = this.list.filter(function(item, i) {
  return item.category == 'special';
}); 

Polymer also supports inline functions/filers now, so you could do something like this:

<template repeat="{{l in sort(list)}}">

created: function() {
  this.list = [6,5,4,3,2,1];
},
sort: function() {
  this.list.sort();
  return this.list;
}

Additional info in this bug: https://github.com/Polymer/docs/issues/435


Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/bb1a3668-6969-450c-ab4b-47c6b5016e0a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Elliott Sprehn

unread,
Aug 1, 2014, 1:58:36 PM8/1/14
to Eric Bidelman, moor...@gmail.com, polymer-dev
On Fri, Aug 1, 2014 at 10:42 AM, Eric Bidelman <ebi...@gmail.com> wrote:
The data binding system is smart in that it maintains a reference to the nodes it produces in the dom, based on the data model. Unless your items physically change location in the array, they will be left intact in the DOM. Only the minimal changes you make to the item's model will be changed in the DOM.

One thing you can do is maintain the origin array as the source of truth, and setup a parallel filtered/sorted version of the array that you template repeat over.  Filter example:

<template repeat="{{item, i in filteredList}}">

this.filteredListed = this.list.filter(function(item, i) {
  return item.category == 'special';
}); 

Polymer also supports inline functions/filers now, so you could do something like this:

<template repeat="{{l in sort(list)}}">

created: function() {
  this.list = [6,5,4,3,2,1];
},
sort: function() {
  this.list.sort();
  return this.list;
}


This doesn't really work for complex values that are sorted with a comparator since the data binding system won't understand how to update them if the sort changes.

ex.

sort: function() {
  this.list.sort(function(a, b) {
     return a.name.localeCompare(b.name);
  });
  return this.list;
},

The binding system won't understand to resort the array when the name property changes.

You'll need to fire events and reassign the array value whenever a property the sort depends on changes. Hopefully we'll get support for sort by clauses in template binding and then you could do:

<template repeat="{{ user in users sort by user.name }}">

or something of that nature.

- E

Arthur Evans

unread,
Aug 2, 2014, 11:42:50 AM8/2/14
to Eric Bidelman, moor...@gmail.com, polymer-dev
Actually, since observation is on the array in this case, you don't need to include the sort function in the binding -- resorting the array should cause the DOM nodes to reorder. Here's a really rough take:


If you can sort your array in place, the binding system should be able to track it. It still needs to shuffle the DOM nodes around, but hopefully it's cheaper than discading and recreating them.

On the other hand, filtering by adding and removing items from the array can be expensive because DOM nodes get discarded and recreated. It may be preferable to filter using CSS, if possible.

 (One way to experiment with data binding: use DevTools to apply a style directly to one or more of the bound DOM nodes. This makes it easy to see when the data binding system has preserved the actual DOM nodes, or just created a new node.)

Arthur


On Fri, Aug 1, 2014 at 10:42 AM, Eric Bidelman <ebi...@gmail.com> wrote:

黎政杨

unread,
Aug 2, 2014, 10:52:53 PM8/2/14
to polym...@googlegroups.com
Thanks all of you!
Reply all
Reply to author
Forward
0 new messages