lodash like utility/algorithms library for D

aliak something at something.com
Fri Sep 28 14:02:48 UTC 2018


Hi,

I've been working for fun on a library [0] that is inspired by a 
library from the javascript world called lodash [1]. I basically 
liked the flexibility and thought I'd try and implement a few 
things as it was about the time I started learning D. It 
basically tried to do the same with algorithms as in lodash but 
adds the usage of Optional!T and Expect!(T, U) as ways to returns 
results.

The readme has some more info on how things were approached: 
https://github.com/aliak00/ddash

I've also been inspired by Scala, so stuff from there also got 
thrown in (e.g. Try). I still consider this library largely 
experimental, but it's turning out nice IMO.

Anyway, code:

import std.experimental.all;

void main() {
     import ddash:
         flatMap,
         try_,
         cond,
         compact,
         isFalsey,
         differenceBy;

     // This could throw.
     alias toInt = (string str) => str.to!int;

     // Call toInt using try_ and flatMap so that you only have
     // valid data points
     alias parseDataSet = (arr) => arr.flatMap!(try_!toInt);

     auto cosmicPoints = dataSets
         .map!parseDataSet
          // Get rid of data sets that are empty
         .compact!isFalsey
         // Convert them to CosmicDataPoint type
         .map!(arr => CosmicDataPoint(arr.sum))
         // Remove the known dead-end values by getting a 
difference set
         // based on the "value" member type
         // This can also be:
         // .difference!((a, b) => a.value == b.value)(...)
         // Or in the case of a D value type just:
         // .difference!(...)
         .differenceBy!"value"(knownDeadEndValues);

     assert(cosmicPoints.walkLength == 3);

     // Pattern match on CosmicDataPoint types and process 
accordingly
     alias process = cond!(
         CosmicDataPoint(29), processBlackMatter,
         CosmicDataPoint(30), processGravitationalWave,
         a => a.value > 30 && a.value < 100, processPromisingData,
         a => writeln("This data is useless: ", a),
     );

     cosmicPoints.each!process;
}

// Simulated data sets that result in CosmicDataPoint
immutable dataSets = [
     ["2", "3", "2"],            // Produces CosmicDataPoint(7)
     ["22", "~1", "7"],          // Produces CosmicDataPoint(29)
     ["!$", "88", "3"],          // Produces CosmicDataPoint(91)
     ["junk", "junk", "junk"],   // All junk data points
     ["99", "44"],               // Produces CosmicDataPoint(143)
];

// A cosmic data point
static struct CosmicDataPoint {
     int value;
}

// Simulate values that you know occur but are a dead end
auto knownDeadEndValues = [1, 7, 42].map!(a => 
CosmicDataPoint(a));

// Define some data processing functions
static void processBlackMatter(CosmicDataPoint) {
     writeln("processing black matter discovery");
}
static void processGravitationalWave(CosmicDataPoint) {
     writeln("processing gravitational wave");
}
static void processPromisingData(CosmicDataPoint) {
     writeln("processing data that's close");
}

Cheers,
- Ali

[0] https://ddash.dub.pm
[1] https://lodash.com/


More information about the Digitalmars-d-announce mailing list