I got a list of strings,on which I would like to do an operation which concats each item with rest of the items. The below test fails at the moment, I think the join is not the correct linq method I should be using- can you please let me know how to get this done? The pattern of the output should tell how the projection should be,if not the rule is simple:take one item and concatenate with all the other items and then move to the next item.Test below:
[Test]
public void Should_concatenate_all_items()
{
var items = new List<string> {"a", "b", "c", "d"};
var concatenatedList = items .Join(items , x => x, y => y, (x, y) => string.Concat(x, y));
foreach (var item in concatenatedList)
{
//Should output:ab
//Should output:ac
//Should output:ad
//Should output:bc
//Should output:bd
//Should output:cd
Console.WriteLine(item);
}
}
Note: I'm using .NET 3.5.
You could use something like this:
var concatenatedList =
from x in items.Select((str, idx) => new { str, idx })
from y in items.Skip(x.idx + 1)
select x.str + y;
Or in fluent syntax:
var concatenatedList =
items.Select((str, idx) => new { str, idx })
.SelectMany(x => items.Skip(x.idx + 1), (x, y) => x.str + y);
I think my solution may be overkill, but in real world situations it is probably more helpful. Also, I could not find a clean way to do it in Linq. Linq's Except does not seem suited for this.
You can use an IEnumerator to enumerate the values for you.
public class ConcatEnum : IEnumerator
{
public List<String> _values;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position1 = 0;
int position2 = 0;
public ConcatEnum(List<String> list)
{
_values = list;
}
public bool MoveNext()
{
position2 = Math.Max(position2 + 1, position1 + 1);
if (position2 > _values.Count - 1){
position1++;
position2 = position1 + 1;
}
return position1 < _values.Count - 1;
}
public void Reset()
{
position1 = 0;
position2 = 0;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public String Current
{
get
{
try
{
return _values[position1] + _values[position2];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public IEnumerator GetEnumerator()
{
this.Reset();
while (this.MoveNext())
{
yield return Current;
}
}
}
Call it like this:
var items = new List<string> { "a", "b", "c", "d" };
foreach (var i in new ConcatEnum(items))
{
//use values here
}
var concatenatedList = (from i in items
from x in items
where i != x
select string.Concat(i, x)).ToList();
For the exact output that you listed:
var concatenatedList = (from i in items
from x in items
where i != x && items.IndexOf(i) < items.IndexOf(x)
select string.Concat(i, x)).ToList();
Related
I have an array list of List<string> that contains values in the following order [100g, 1.5kg, 250g] now when I try to sort them I am not getting the expected result and it is sorting in the following order.
I am using array.OrderBy(x => x);
[1.5kg, 100g, 250g]
How can I sort them according to their weight?
the correct should be:
[100g, 250g, 1.5kg]
try parse to g and sort it
public void GOGO()
{
List<string> ay = new List<string>()
{
"1.5kg","100g","1600g"
};
IOrderedEnumerable<string> orderList = ay.OrderBy(x => WeightG(x));
foreach(string s in orderList)
{
Console.WriteLine(s);//here
}
}
public int WeightG(string weighStr)
{
if (weighStr.Contains("kg"))
{
string num = weighStr.Split('k')[0];
return (int)(float.Parse(num) * 1000);
}
if (weighStr.Contains("g"))
{
string num = weighStr.Split('g')[0];
return int.Parse(num);
}
return 0;
}
I have a simpler and elegant solution with less code:
string[] a = new string[] { "7.2kg", "1.5kg", "100g", "250g" };
var lstKg = a.ToList().Where(x => x.Contains("kg")).Select(y => double.Parse(y.Replace("kg", String.Empty))).OrderBy(k=>k).Select(o=>o+"kg").ToList();
var lstG = a.ToList().Where(x => !lstKg.Contains(x)).Select(y => double.Parse(y.Replace("g", String.Empty))).OrderBy(k=>k).Select(o =>o+"g").ToList();
lstG.AddRange(lstKg);
lstG.ForEach(item => Console.WriteLine(item));
You can normalize all array elements to g. Then sort as numbers and finally convert to g or kg.
sample code:
private string[] normalaizeArray(string[] inputArray)
{
for (int i= 0 ; i < inputArray.Length; i++)
{
if(inputArray[i].Contains('k'))
{
inputArray[i] = (float.Parse(inputArray[i].Split('k')[0]) * 1000).ToString();
}
else
{
inputArray[i] = inputArray[i].Replace("g", "");
}
}
inputArray = inputArray.OrderBy(x => int.Parse(x)).ToArray();
for (int i = 0; i < inputArray.Length; i++)
{
if(int.Parse(inputArray[i])>1000)
inputArray[i] = (float.Parse(inputArray[i])/1000).ToString() + "kg";
else
inputArray[i] = inputArray[i] + 'g';
}
return inputArray;
}
Hope this helps!
I have an array of string, I want to take all the string in an interval of this array until string does not contains something.
Something like:
string [] arrayReading = {
"e","x","a","takefromhere",
"keeptaking","keeptaking","dont'ttakefromhere","m","p","l","e"
};
I have tried:
List<string> result = null;
for (int i = 0; i < arrayReading.Length; i++)
{
if (arrayReading[i].Contains("takefromhere"))
{
result.Add(arrayReading[i]);
if (!arrayReading[i + 1].Contains("dont'ttakefromhere"))
{
result.Add(arrayReading[i + 1]);
if (!arrayReading[i + 2].Contains("dont'ttakefromhere"))
{
rescription.Add(arrayReading[i + 1]);
}
}
}
}
Seems working but it's not really dynamic as I want it, because maybe I need to take 20 values between "takefromhere" and "don'ttakefromhere".
When querying you can try Linq:
using System.Linq;
...
List<string> result = arrayReading
.SkipWhile(item => item != "takefromhere")
.TakeWhile(item => item != "dont'ttakefromhere")
.ToList();
Or if you want good old loop solution:
List<string> result = new List<string>();
bool taking = false;
foreach (string item in arrayReading) {
if (!taking)
taking = item == "takefromhere";
if (taking) {
if (item == "dont'ttakefromhere")
break;
result.Add(item);
}
}
Let's have a look:
Console.Write(string.Join("; ", result));
Outcome:
takefromhere; keeptaking; keeptaking
I am trying to compare a set of integers (say alpha) with the result i am getting (say result)
if result is in alpha i should be able to get the output as mentioned in example below
alpha = 0,1,2,3,4,5,6,7
result = 0,5,6
Final answer should be ABBBBAAB
and what i am getting is ABBBBBBB BBBBBABB BBBBBBAB
As per code
public static int[] alpha = new int[8]
{
0,1,2,3,4,5,6,7
};
public static void Main(string[] args)
{
// Lines of code
foreach (var jagged in manager.JaggedList)
{
// Lines of code
foreach (var item in Items)
{
Console.Write(item.Number); //For Ex output here is (0,5,6)
List<int> result = new List<int>();
result.Add(item.Number);
foreach (var Var in result)
{
for (int i = 0; i < alpha.Length; i++)
{
if (result.Contains(alpha[i]))
{
Console.Write(alpha[A]);
}
else
{
Console.Write(alpha[B]);
}
}
}
Console.WriteLine();
}
}
Final answer should be ABBBBAAB
and what i am getting is ABBBBBBB BBBBBABB BBBBBBAB
If Linq is acceptable then just use
alpha
.Select(a => result.Contains(a) ? "A" : "B")
.ToList()
.ForEach(x => Console.Write(x));
using foreach loops
foreach(var a in alpha) {
var found = false;
foreach(var r in result) {
if(a == r) {
found = true;
}
}
Console.Write(found ? "A" : "B");
}
Where can I find a simple (as much as possible, but no simpler!) implementation of an LR(1) parser generator?
I'm not looking for performance, just the ability to generate the LR(1) states (item sets).
C++, C#, Java, and Python would all work for me.
I've written a very simple one in C# and wanted to share it here.
It basically populates the action lookup table, which tells you which state to shift to or which rule to use for reduction.
If the number is nonnegative, then it denotes a new state; if it's negative, then its one's complement (i.e. ~x) denotes the rule index.
All you need now is to make a lexer and to do the actual parsing with the action table.
Note 1: It might be quite slow at generating the states for a real-world grammar, so you might want to think twice before using it in production code!
Note 2: You might want to double-check its correctness, since I've only checked it a bit.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using size_t = System.UInt32;
public class LRParser
{
private string[] symbols; // index => symbol
private IDictionary<string, size_t> interned = new SortedDictionary<string, size_t>(); // symbol => index
private int[/*state*/, /*lookahead*/] actions; // If >= 0, represents new state after shift. If < 0, represents one's complement (i.e. ~x) of reduction rule.
public LRParser(params KeyValuePair<string, string[]>[] grammar)
{
this.interned.Add(string.Empty, new size_t());
foreach (var rule in grammar)
{
if (!this.interned.ContainsKey(rule.Key))
{ this.interned.Add(rule.Key, (size_t)this.interned.Count); }
foreach (var symbol in rule.Value)
{
if (!this.interned.ContainsKey(symbol))
{ this.interned.Add(symbol, (size_t)this.interned.Count); }
}
}
this.symbols = this.interned.ToArray().OrderBy(p => p.Value).Select(p => p.Key).ToArray();
var syntax = Array.ConvertAll(grammar, r => new KeyValuePair<size_t, size_t[]>(this.interned[r.Key], Array.ConvertAll(r.Value, s => this.interned[s])));
var nonterminals = Array.ConvertAll(this.symbols, s => new List<size_t>());
for (size_t i = 0; i < syntax.Length; i++) { nonterminals[syntax[i].Key].Add(i); }
var firsts = Array.ConvertAll(Enumerable.Range(0, this.symbols.Length).ToArray(), s => nonterminals[s].Count > 0 ? new HashSet<size_t>() : new HashSet<size_t>() { (size_t)s });
int old;
do
{
old = firsts.Select(l => l.Count).Sum();
foreach (var rule in syntax)
{
foreach (var i in First(rule.Value, firsts))
{ firsts[rule.Key].Add(i); }
}
} while (old < firsts.Select(l => l.Count).Sum());
var actions = new Dictionary<int, IDictionary<size_t, IList<int>>>();
var states = new Dictionary<HashSet<Item>, int>(HashSet<Item>.CreateSetComparer());
var todo = new Stack<HashSet<Item>>();
var root = new Item(0, 0, new size_t());
todo.Push(new HashSet<Item>());
Closure(root, todo.Peek(), firsts, syntax, nonterminals);
states.Add(new HashSet<Item>(todo.Peek()), states.Count);
while (todo.Count > 0)
{
var set = todo.Pop();
var closure = new HashSet<Item>();
foreach (var item in set)
{ Closure(item, closure, firsts, syntax, nonterminals); }
var grouped = Array.ConvertAll(this.symbols, _ => new HashSet<Item>());
foreach (var item in closure)
{
if (item.Symbol >= syntax[item.Rule].Value.Length)
{
IDictionary<size_t, IList<int>> map;
if (!actions.TryGetValue(states[set], out map))
{ actions[states[set]] = map = new Dictionary<size_t, IList<int>>(); }
IList<int> list;
if (!map.TryGetValue(item.Lookahead, out list))
{ map[item.Lookahead] = list = new List<int>(); }
list.Add(~(int)item.Rule);
continue;
}
var next = item;
next.Symbol++;
grouped[syntax[item.Rule].Value[item.Symbol]].Add(next);
}
for (size_t symbol = 0; symbol < grouped.Length; symbol++)
{
var g = new HashSet<Item>();
foreach (var item in grouped[symbol])
{ Closure(item, g, firsts, syntax, nonterminals); }
if (g.Count > 0)
{
int state;
if (!states.TryGetValue(g, out state))
{
state = states.Count;
states.Add(g, state);
todo.Push(g);
}
IDictionary<size_t, IList<int>> map;
if (!actions.TryGetValue(states[set], out map))
{ actions[states[set]] = map = new Dictionary<size_t, IList<int>>(); }
IList<int> list;
if (!map.TryGetValue(symbol, out list))
{ map[symbol] = list = new List<int>(); }
list.Add(state);
}
}
}
this.actions = new int[states.Count, this.symbols.Length];
for (int i = 0; i < this.actions.GetLength(0); i++)
{
for (int j = 0; j < this.actions.GetLength(1); j++)
{ this.actions[i, j] = int.MinValue; }
}
foreach (var p in actions)
{
foreach (var q in p.Value)
{ this.actions[p.Key, q.Key] = q.Value.Single(); }
}
foreach (var state in states.OrderBy(p => p.Value))
{
Console.WriteLine("State {0}:", state.Value);
foreach (var item in state.Key.OrderBy(i => i.Rule).ThenBy(i => i.Symbol).ThenBy(i => i.Lookahead))
{
Console.WriteLine(
"\t{0}: {1} \xB7 {2} | {3} → {0}",
this.symbols[syntax[item.Rule].Key],
string.Join(" ", syntax[item.Rule].Value.Take((int)item.Symbol).Select(s => this.symbols[s]).ToArray()),
string.Join(" ", syntax[item.Rule].Value.Skip((int)item.Symbol).Select(s => this.symbols[s]).ToArray()),
this.symbols[item.Lookahead] == string.Empty ? "\x04" : this.symbols[item.Lookahead],
string.Join(
", ",
Array.ConvertAll(
actions[state.Value][item.Symbol < syntax[item.Rule].Value.Length ? syntax[item.Rule].Value[item.Symbol] : item.Lookahead].ToArray(),
a => a >= 0 ? string.Format("state {0}", a) : string.Format("{0} (rule {1})", this.symbols[syntax[~a].Key], ~a))));
}
Console.WriteLine();
}
}
private static void Closure(Item item, HashSet<Item> closure /*output*/, HashSet<size_t>[] firsts, KeyValuePair<size_t, size_t[]>[] syntax, IList<size_t>[] nonterminals)
{
if (closure.Add(item) && item.Symbol >= syntax[item.Rule].Value.Length)
{
foreach (var r in nonterminals[syntax[item.Rule].Value[item.Symbol]])
{
foreach (var i in First(syntax[item.Rule].Value.Skip((int)(item.Symbol + 1)), firsts))
{ Closure(new Item(r, 0, i == new size_t() ? item.Lookahead : i), closure, firsts, syntax, nonterminals); }
}
}
}
private struct Item : IEquatable<Item>
{
public size_t Rule;
public size_t Symbol;
public size_t Lookahead;
public Item(size_t rule, size_t symbol, size_t lookahead)
{
this.Rule = rule;
this.Symbol = symbol;
this.Lookahead = lookahead;
}
public override bool Equals(object obj) { return obj is Item && this.Equals((Item)obj); }
public bool Equals(Item other)
{ return this.Rule == other.Rule && this.Symbol == other.Symbol && this.Lookahead == other.Lookahead; }
public override int GetHashCode()
{ return this.Rule.GetHashCode() ^ this.Symbol.GetHashCode() ^ this.Lookahead.GetHashCode(); }
}
private static IEnumerable<size_t> First(IEnumerable<size_t> symbols, IEnumerable<size_t>[] map)
{
foreach (var symbol in symbols)
{
bool epsilon = false;
foreach (var s in map[symbol])
{
if (s == new size_t()) { epsilon = true; }
else { yield return s; }
}
if (!epsilon) { yield break; }
}
yield return new size_t();
}
private static KeyValuePair<K, V> MakePair<K, V>(K k, V v) { return new KeyValuePair<K, V>(k, v); }
private static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
var parser = new LRParser(
MakePair("start", new string[] { "exps" }),
MakePair("exps", new string[] { "exps", "exp" }),
MakePair("exps", new string[] { }),
MakePair("exp", new string[] { "INTEGER" })
);
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
LRSTAR 9.1 is a minimal LR(1) and LR(*) parser generator. You can use it to verify that your parser generator is giving the correct states, by using option '/s'. LRSTAR has been tested against HYACC and found to be giving the correct LR(1) states. 20 grammars are provided with LRSTAR and 6 Microsoft Visual Studio projects.
I have a custom class containing 2 public variables: 1 is a string and 1 is an integer. I then make a list of this class, in the list I need the string of the class to be unique, if the string already exists in the list I don't want to add it again but I do want to combine the corresponding integers. here is an example of the custom class and list.
public class myItems
{
public string itemName;
public int count;
}
List<myItems> items = new List<myItems>();
myItems e = new myItems();
e.symbol = "pencil";
e.count = 3;
items.Add(e);
myItems e1 = new myItems();
e1.symbol = "eraser";
e1.count = 4;
items.Add(e1);
myItems e2 = new myItems();
e1.symbol = "pencil";
e1.count = 3;
items.Add(e5);
So for the final list i want to it contain: pencil 7, eraser 4. I have been using the contains function on the list to check if it already exists but it only returns true if both the string and integer are the same.
Is there a way to only match on the string?
Another way to do it would be to use LINQ:
public class myItems
{
public string itemName;
public int count;
}
List<myItems> items = new List<myItems>();
myItems e = new myItems();
e.symbol = "pencil";
e.count = 3;
Add(items, e);
myItems e1 = new myItems();
e1.symbol = "eraser";
e1.count = 4;
Add(items, e1);
myItems e2 = new myItems();
e1.symbol = "pencil";
e1.count = 3;
Add(items, e5);
public void Add(List<myItems> list, myItems newItem)
{
var item = list.SingleOrDefault(x => x.symbol == newItem.symbol);
if(item != null)
{
item.count += newItem.count;
}
else
{
list.Add(newItem);
}
}
A dictionary might be well suited for this problem:
readonly Dictionary<string, int> _dict = new Dictionary<string, int>();
void InsertOrUpdate(string name, int count)
{
int previousCount = 0;
// item already in dictionary?
if (_dict.TryGetValue(name, out previousCount))
{
// add to count
count += previousCount;
}
_dict[name] = count;
}
void Main()
{
InsertOrUpdate("pencil", 3);
InsertOrUpdate("eraser", 3);
InsertOrUpdate("pencil", 4);
// print them
foreach (var item in _dict)
Console.WriteLine(item.Key + " " + item.Value);
}
You could add an Equals method to your class, or use LINQ with something like
items.Where(i => i.itemName == "pencil")
However, if all you are doing is keeping track of how many 'items' you have, would a Dictionary that maps itemNames to counts solve your problem easier? Then you would be able to do things like
// Assuming you want to add a new 'pencil' with a count of 3
int oldCount = 0;
items.TryGetValue("pencil", out oldCount);
items["pencil"] = oldCount + 3;
Usually see something like this called a Bag
Sure, write a custom Equals method
public override bool Equals(object o)
{
MyItems mi = o as MyItems;
if (mi == null)
return false;
if (itemName == null)
return mi.itemName == null;
return itemName.Equals(mi.itemName);
}
public override int HashCode()
{
return (itemName ?? string.Empty).HashCode();
}
That being said, you really should be using a dictionary/hash table instead, since a dictionary provides much faster lookup when you know what you want. A List implementation will cause the list to be searched in its entirety every time you want to add a MyItem to the list.
when you check if it contains and it returs true than you get the index and add the number to it. use that logic. it will work.