Skip to content

Instantly share code, notes, and snippets.

@giuliohome
Last active May 22, 2017 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giuliohome/fe082cdd508a12c877709e1134685ed9 to your computer and use it in GitHub Desktop.
Save giuliohome/fe082cdd508a12c877709e1134685ed9 to your computer and use it in GitHub Desktop.
Porting JavaScript transducer (http://raganwald.com/2017/04/30/transducers.html) to CSharp based on the .net lib https://github.com/bmurphy1976/transducers-dotnet
using System;
using System.Collections.Generic;
using System.Linq;
using TransducersNet;
namespace TransducerSample2CSharp
{
class Program
{
private static IEnumerable<string> asStream(string[] iterable)
{
foreach (var item in iterable)
{
yield return item;
}
}
static void Main(string[] args)
{
string logContents = @"1a2ddc2, 5f2b932
f1a543f, 5890595
3abe124, bd11537
f1a543f, 5f2b932
f1a543f, bd11537
f1a543f, 5890595
1a2ddc2, bd11537
1a2ddc2, 5890595
3abe124, 5f2b932
f1a543f, 5f2b932
f1a543f, bd11537
f1a543f, 5890595
1a2ddc2, 5f2b932
1a2ddc2, bd11537
1a2ddc2, 5890595";
var streamOfLines = asStream(logContents.Replace("\r", "").Split('\n'));
var xform = Composer<string>
.Map(x => x.Split(new string[] { ", " }, StringSplitOptions.None))
.Map(sortedTransformation)
.Filter(x => !x.skip)
.Compose();
var output = Transducer
.Transduce(xform, collectTransaction, new List<Transaction>(), streamOfLines);
//.ToList(xform, streamOfLines);
//.Transduce(xform, collectUser, new Dictionary<string, List<string>>(), streamOfLines);
foreach (var item in output)
{
//Console.WriteLine(item.Key +": " + String.Join("->", item.Value));
//Console.WriteLine(item.Take(1).FirstOrDefault() + ": " + String.Join("->", item.Skip(1)));
//Console.WriteLine(item.User + ": " + item.From + " -> " + item.To);
Console.WriteLine(item.total + ": " + item.From + " -> " + item.To);
}
var stats = output.Aggregate(new List<Transaction>(),
(acc, val) =>
{
var curr = acc.FirstOrDefault()?.total ?? 0;
if (val.total == curr)
{
acc.Add(val);
}
if (val.total > curr)
{
acc = new List<Transaction>() { val };
}
return acc;
}
);
Console.WriteLine("STATS");
foreach (var item in stats)
{
Console.WriteLine(item.total + ": " + item.From + " -> " + item.To);
}
Console.ReadLine();
}
private static Func<Dictionary<string, List<string>>, string[], Dictionary<string, List<string>>> collectUser =
(result, value) =>
{
string key = userKey(value);
List<string> list;
if (result.ContainsKey(key))
{
list = result[key];
}
else
{
list = new List<string>() { "user: " + key };
result.Add(key, list);
}
list.Add(userVal(value));
return result;
};
private static Func<List<Transaction>, UserTransaction, List<Transaction>> collectTransaction =
(result, value) =>
{
var found = result.FirstOrDefault(t => t.From.Equals(value.From) && t.To.Equals(value.To));
if (found == null)
{
result.Add(new Transaction() { From = value.From, To = value.To, total = 1 });
}
else
{
found.total++;
}
return result;
};
private static string userKey(string[] value)
{
return value[0];
}
private static string userVal(string[] value)
{
return value[1];
}
private static Dictionary<string, List<string>> userMap = new Dictionary<string, List<string>>();
private static UserTransaction sortedTransformation(string[] val)
{
string key = userKey(val);
List<string> list;
if (userMap.ContainsKey(key))
{
list = userMap[key];
list.Add(userVal(val));
var tra = new UserTransaction() { User = list[0], From = list[1], To = list[2] };
list.RemoveAt(1);
return tra;
}
else
{
list = new List<string>() { "user: " + key };
userMap.Add(key, list);
list.Add(userVal(val));
return new UserTransaction() { skip = true };
}
}
}
public class UserTransaction
{
public bool skip;
public string User;
public string From;
public string To;
}
public class Transaction
{
public int total;
public string From;
public string To;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment