Giter VIP home page Giter VIP logo

Comments (4)

Mistyputt avatar Mistyputt commented on May 25, 2024

I've played around with a naive implementation:

function mapArrayWithIndex<A, B>(f: (a: A, i: number) => B, array: A[], offset: number): [B[], number] {
  const result = new Array(array.length);
  for (let i = 0; i < array.length; ++i) {
    result[i] = f(array[i], offset + i);
  }
  return [result, offset + array.length];
}

function mapNodeWithIndex<A, B>(f: (a: A, i: number) => B, node: Node, depth: number, offset: number, adjust: number): [Node, number] {
  if (depth !== 0) {
    const { array } = node;
    var innerOffset = offset;
    const result = new Array(array.length);
    for (let i = 0; i < array.length; ++i) {
      let [res, newOffset] = mapNodeWithIndex(f, array[i], depth - 1, innerOffset, adjust * 32);
      innerOffset = newOffset;
      result[i] = res
    }
    return [new Node(node.sizes, result), innerOffset];
  } else {
    let [res, newOffset] = mapArrayWithIndex(f, node.array, offset);
    return [new Node(undefined, res), newOffset];
  }
}

function mapPrefixWithIndex<A, B>(f: (a: A, i: number) => B, prefix: A[], length: number): B[] {
  const newPrefix = new Array(length);
  for (let i = length - 1; 0 <= i; --i) {
    newPrefix[i] = f(prefix[i], length - 1 - i);
  }
  return newPrefix;
}

function mapAffixWithIndex<A, B>(f: (a: A, i: number) => B, suffix: A[], length: number, totalLength: number): B[] {
  const priorLength = totalLength - length;
  const newSuffix = new Array(length);
  for (let i = 0; i < length; ++i) {
    newSuffix[i] = f(suffix[i], priorLength + i);
  }
  return newSuffix;
}

/**
 * Applies a function to each element in the given list, and its index, and returns a
 * new list of the values that the function return.
 *
 */
export function mapWithIndex<A, B>(f: (a: A, i: number) => B, l: List<A>): List<B> {
  return new List(
    l.bits,
    l.offset,
    l.length,
    mapPrefixWithIndex(f, l.prefix, getPrefixSize(l)),
    l.root === undefined ? undefined : mapNodeWithIndex(f, l.root, getDepth(l), getPrefixSize(l), 1)[0],
    mapAffixWithIndex(f, l.suffix, getSuffixSize(l), l.length)
  );
}

Maybe one could use the depth and branchingFactor instead but this seems performance-wise to already fare better than zipWith. Here are my rudimentary benchmark results:

List.map 10                   36818486.05 op/s ±  0.54%   (86 samples)
List.mapWithIndex 10          32894014.39 op/s ±  0.39%   (88 samples)
List.zipWith 10               4332197.10 op/s ±  0.63%   (84 samples)
List.map 30000                14337.09 op/s ±  0.71%   (88 samples)
List.mapWithIndex 30000       11587.69 op/s ±  0.54%   (88 samples)
List.zipWith 30000             1240.52 op/s ±  0.61%   (87 samples)

from list.

carleryd avatar carleryd commented on May 25, 2024

@Mistyputt I just ran into the same issue where I want to know which position in a row an element was clicked. The row is created using map function.
I would like to do the following

L.map((x, i) => <Poster content={x} position={i} />, contentL)

I guess a workaround for now can be to use indexOf

from list.

paldepind avatar paldepind commented on May 25, 2024

Thanks for opening the issue and providing feedback. I definitely agree that it would be nice to offer an easy way to map with an index.

I think your mapWithIndex implementation looks great @Mistyputt. Would you like to add it in a PR? 😄

from list.

Mistyputt avatar Mistyputt commented on May 25, 2024

Absolutely!

I did work around a few issues building the project when trying out that implementation and would feel better if I had a "clean" project when submitting the PR. After cloning I ran npm install, then npm run build. That failed with errors on ts-toolbelt and devtoolsFormatters:

❯ npm run build

> [email protected] build /Users/thomas/git/github/funkia/list3
> npm run build-es6; npm run build-cmjs


> [email protected] build-es6 /Users/thomas/git/github/funkia/list3
> tsc -P ./tsconfig-build.json --outDir 'dist/es' --module es2015

node_modules/@types/ramda/index.d.ts:546:28 - error TS2307: Cannot find module 'ts-toolbelt'.

546 import { A, F, T, O } from "ts-toolbelt";
                               ~~~~~~~~~~~~~

src/devtools.ts:15:8 - error TS2339: Property 'devtoolsFormatters' does not exist on type '(Window & typeof globalThis) | Global'.
  Property 'devtoolsFormatters' does not exist on type 'Window & typeof globalThis'.

15 if (gw.devtoolsFormatters === undefined) {
          ~~~~~~~~~~~~~~~~~~

src/devtools.ts:16:6 - error TS2339: Property 'devtoolsFormatters' does not exist on type '(Window & typeof globalThis) | Global'.
  Property 'devtoolsFormatters' does not exist on type 'Window & typeof globalThis'.

16   gw.devtoolsFormatters = [];
        ~~~~~~~~~~~~~~~~~~

src/devtools.ts:26:4 - error TS2339: Property 'devtoolsFormatters' does not exist on type '(Window & typeof globalThis) | Global'.
  Property 'devtoolsFormatters' does not exist on type 'Window & typeof globalThis'.

26 gw.devtoolsFormatters.push({
      ~~~~~~~~~~~~~~~~~~


Found 4 errors.

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build-es6: `tsc -P ./tsconfig-build.json --outDir 'dist/es' --module es2015`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build-es6 script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/thomas/.npm/_logs/2020-04-30T21_15_23_326Z-debug.log

> [email protected] build-cmjs /Users/thomas/git/github/funkia/list3
> tsc -P ./tsconfig-build.json

src/devtools.ts:15:8 - error TS2339: Property 'devtoolsFormatters' does not exist on type '(Window & typeof globalThis) | Global'.
  Property 'devtoolsFormatters' does not exist on type 'Window & typeof globalThis'.

15 if (gw.devtoolsFormatters === undefined) {
          ~~~~~~~~~~~~~~~~~~

src/devtools.ts:16:6 - error TS2339: Property 'devtoolsFormatters' does not exist on type '(Window & typeof globalThis) | Global'.
  Property 'devtoolsFormatters' does not exist on type 'Window & typeof globalThis'.

16   gw.devtoolsFormatters = [];
        ~~~~~~~~~~~~~~~~~~

src/devtools.ts:26:4 - error TS2339: Property 'devtoolsFormatters' does not exist on type '(Window & typeof globalThis) | Global'.
  Property 'devtoolsFormatters' does not exist on type 'Window & typeof globalThis'.

26 gw.devtoolsFormatters.push({
      ~~~~~~~~~~~~~~~~~~

As no one else has reported this I feel I'm missing something obvious. When I played around with the mapWithIndex implementation I just commented out src/devtools.ts and ran the build-cmjs only, not the es6 that additionally failed on ts-toolbelt.

I built with node v10.19.0. Any pointers?

from list.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.