adamhaile / s-array Goto Github PK
View Code? Open in Web Editor NEWUtility methods for working with arrays in S.js
Utility methods for working with arrays in S.js
Do you have any plans (or any guidance) for implementing "S" versions other data structures (e.g. Map, Set, etc.)? SArray is exceedingly useful and S-versions of other data structures would be just as useful I imagine.
Hi Adam,
It would be nice if .map
would provide the index value as the second argument to its callback, or that the documentation clearly states that contrarily to Array::map
, the index is provided as the third argument ;)
Typically, providing the index as second argument, one could write
lines.map (line,index) => …
or
lines().map (line,index) => …
(I'm a bit unclear on what the value
currently provided in the second argument to enter
would be, as well, but I haven't needed it.)
Hey Adam,
would it be possible to add a Symbol.iterator
property for better interop?
For example, with SArrays the following fails with a .map() is not iterable
error:
const arr = SArray([1, 2, 3, 3, 4, 5]);
const set = new Set(arr.map(i => i > 2));
Thanks!
from index.d.ts:
export interface SArray<T> {... }
export interface SDataArray<T> extends SArray<T>
I would proffered this be written as:
export interface SArray<T> extends ReadonlyArray<T> {
// only S-Array specific function mentioned here
}
export interface SDataArray<T> extends SArray<T>, Array<T> {
// only S-Array specific function mentioned here
}
Obviously the implication are
The reason is this would allow general (generic) function to be written that can handled both types. Also converting code to-and-from standard array / s-array.
What is your opinion?
Thank you.
I would like to update a signal in an array in-place at an index, analogous to array[index] = value
with a standard array. I haven't found a way to do so with a built-in SArray method.
I discovered that .find()
returns a signal rather than the raw value, and I hoped this would be a means of updating an item in the array. However, that does not appear to be the case. It seems that (like the other methods SArray provides) this returns a result of the original SArray but doesn't update the original SArray.
For example, I would expect this code:
const testArray = SArray([1, 2, 3]);
S.root(() => {
S(function logFromComputation () {
console.log("Logging from computation");
console.log(testArray().join(', '));
});
const testItem = testArray.find(item => item === 3);
testItem(5);
console.log("Logging explicitly");
console.log(testArray().join(', '));
})
To result in:
Logging from computation
1, 2, 3
Logging from computation
1, 2, 5
Logging explicitly
1, 2, 5
But instead it results in:
Logging from computation
1, 2, 3
Logging explicitly
1, 2, 3
A couple of workarounds I've thought of:
.splice()
to replace the original value with a new one (kind of ugly, and requires evaluating the signal to get the index since .indexOf()
isn't implemented)()
everywhere the value is used, and I don't think updates to those signals propagate back to the parent SArray)Do you have another recommendation for this use case, or should I go with one of those workarounds?
The native splice method returns an array of the removed items (if any), whereas SArray currently just returns the array itself. As splice is probably not something you'd be using for chaining methods, is there any reason for not keeping it consistent with the native method?
Had another suggestion also that it would be nice to add removeAt and moveItem, e.g. a handy shorthand for splice(index, 1) and one for moving items around in the array.
I'm using this project for building webpages (I've borrowed your amazing content-algorithm from Surplus but instead of the compiler I created a small runtime inspired by ivi-html), and I've come across how many times I find myself using these two utility methods.
If it sounds good I can assemble a pull request. It would require changing some of the existing specs and would of course be a breaking change. I'm not sure what the policy is given that this project is still <1.0.
Cheers on your work on this project! 👍
To match typescript names (and obvious usage):
SArray -> ReadonlySArray
SDataArray -> SArray
This looks like breaking changes. So it will probably not happen like this. But the names are bit confusing.
var array = SArray([1])
console.log(array.length) <-- undefined
I want to use "SArray" for data constructor and type in the same file. I have to use following import construct.
import SArray, { SArray as SArrayType } from "s-array";
function fill() : SArrayType<string> {
const items = SArray(["a", "b", "c"]);
return items;
}
this is import that work or SArray as a funciton
import SArray from "s-array";
function fill() {
const items = SArray(["a", "b", "c"]);
return items;
}
and this type of import make SArray a type
import { SArray } from "s-array";
function fill() : SArray<string> {
return null;
}
I suppose the error can be in way how type definition file is written?
I'm using TypeScript 3 and node/npm
Thank you.
Context: I'm using S.js/SArray in a Surplus application, with a lot of async updates (via socket.io). I'm trying to par down the number of DOM updates, specifically with code that has to deal with multiple operations on SArray; my bottleneck was in code similar to:
var filtering_field = S.data('hello') // value from UI element
var filtering_function = S( (value) =>
return value === filtering_field()
)
var original_list = SArray( [] ) // updated over socket.io
var filtered_list = S( => // displayed using Surplus
return original_list.filter(filtering_function).sort().splice(0,99)
)
In this example, filtering_field
is the value of a UI element, while original_list
is updated over socket.io. The filtered_list
is then displayed using Surplus.
I've been debouncing native values using S.js with code that looks like the following (this is more-or-less my coffeescript code with-parentheses-added for clarity):
var debounce = (src,timeout,conclude) =>
var timer = null
S( () =>
var v = src()
clearTimeout(timer)
timer = setTimeout( ( () => conclude(v) ), timeout )
return
)
return
To create a debounced signal I then use:
var debounced_signal = S.data( null )
debounce( original_signal, timeout, debounced_signal )
However this is clearly sub-optimal when using SArray:
var debounced_array = SArray( [] )
debounce( original_array, timeout, debounced_array )
because the entire SArray gets overwritten every time, which means that .filter
etc. are not optimized on changed values, but are re-applied to the entire Array every time. (Assuming I understand what SArray does!!)
Is there a better way to debounce an SArray?
Hello again :) In newer environments there are methods such as .flatMap
and whatnot - could these possibly be supported?
Not really sure what's happening here, but .includes()
returns a computation instead of a boolean. This caused kind of a headache for a short while trying to figure out why an if conditional was always evaluating to true
.
const a = Sarray([1, 2, 3, 4]);
if (a.includes(5)) {
console.log('always hit!');
}
I cannot find any functionality that would allow me to see elements that were pushed, removed, spliced etc...
I would find this very useful and looks to me like big omission. Also it does not looks complex to implemented - lot of time the element itself is part of the modifying-function argument.
What is your opinion?
Thank you.
btw - Is there any forum where to post questions?
var = SArray([]);
console.log(arr.length); // 1
arr.push("abc");
console.log(arr.length); // 1
Solution would be probably to fix the returned number or remove the .length accessor.
Hi @adamhaile I may not have understood this project. As I understand it:
import SArray from 's-array';
import S, { DataSignal } from 's-js';
const list = SArray<number>([]);
const fn1 = () => {
const listItems = list();
//do some process with listItems
console.log('fn1');
};
const fn2 = () => {
const listItems = list();
//do some process with listItems
console.log('fn2');
};
const fn3 = () => {
const listItems = list();
//do some process with listItems
console.log('fn3');
};
S(() => {
S.freeze(() => {
list.push(1);
list.push(2);
list.push(3);
});
fn1();
fn2();
fn3();
});
S.freeze(() => {
console.log('---------------------');
console.log('push item 4');
list.push(4);
console.log('push item 5');
list.push(5);
console.log('---------------------');
});
output is
fn1
fn2
fn3
---------------------
fn1
fn2
fn3
fn1
fn2
fn3
......
.......
---------------------
This is normal working. Binding s-array'ed objects to UI working well. list.push inserts new dom node and list.splice removes.
But in a real project, arrays are difficult to manage. As in the previous example every list.push(..)
method triggers all functions where list()
is used. This can lead to unexpected results. Also can be performance problem in a large project.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.