Linq Transformations - linq

I have an example class such as:
class Foo
{
Int32 A;
IEnumerable<Int32> B;
}
Is it possible to transform an enumerable of Foo to an enumerable of Int32, which would include the A and the contents of B from all Foo's?
A non-LINQ solution would be:
var ints = new List<Int32>();
foreach (var foo in foos) {
ints.Add(foo.A);
ints.AddRange(foo.B);
}
The closest I could think of is:
var ints = foos.SelectMany(foo => var l = new List { foo.A }; l.AddRange(foo.B); return l);
But I wonder if there is a better solution that creating a temporary list?

This should work:
var results = foos.SelectMany(f => f.B.Concat(new[] { f.A}));
Basic approach is to create a new enumeration with one element by creating an array with one element which is f.A, concatenating this to the existing enumeration of f.B and finally flatten the sequence with SelectMany()

as a List<Int32> per your non-Linq example
var ints = Foo.B.ToList().Add(Foo.A);
Lazy more Linq-ish solution
var ints = Foo.B.Concat(new Int32[] {Foo.A})

var ints = foos.SelectMany(f => f.B.Concat(new int[] { f.A}));
If you specifically need f.A before all elements from f.B:
var ints = foos.SelectMany(f => (new int[] { f.A }).concat(f.B));

Related

sorted function in Swift 2

I'm sorting an Array like this:
var users = ["John", "Matt", "Mary", "Dani", "Steve"]
func back (s1:String, s2:String) -> Bool
{
return s1 > s2
}
sorted(users, back)
But I'm getting this error
'sorted' is unavailable: call the 'sort()' method on the collection
What should be the correct way to use the sort() method here?
Follow what the error message is telling you, and call sort on the collection:
users.sort(back)
Note that in Swift 2, sorted is now sort and the old sort is now sortInPlace, and both are to be called on the array itself (they were previously global functions).
Be careful, this has changed again in Swift 3, where sort is the mutating method, and sorted is the one returning a new array.
Another way to use closure is:
var numbers = [2,4,34,6,33,1,67,20]
var numbersSorted = numbers.sort( { (first, second ) -> Bool in
return first < second
})
Another way is to use closure in a simple way:
users.sort({a, b in a > b})
In swift 2.2 there are multiple ways we can use closures with sort function as follows.
Consider the array
var names:[String] = ["aaa", "ddd", "rrr", "bbb"];
The different options for sorting the array with swift closures are as added
Option 1
// In line with default closure format.
names = names.sort( { (s1: String, s2: String) -> Bool in return s1 < s2 })
print(names)
Option 2
// Omitted args types
names = names.sort( { s1, s2 in return s1 > s2 } )
print(names)
Option 3
// Omitted args types and return keyword as well
names = names.sort( { s1, s2 in s1 < s2 } )
print(names)
Option 4
// Shorthand Argument Names(with $ symbol)
// Omitted the arguments area completely.
names = names.sort( { $0 < $1 } )
print(names)
Option 5
This is the most simple way to use closure in sort function.
// With Operator Functions
names = names.sort(>)
print(names)
var array = [1, 5, 3, 2, 4]
Swift 2.3
let sortedArray = array.sort()
Swift 3.0
let sortedArray = array.sorted()

how to sort a list in Vala using custom Comparator

I'm trying to get a directory listing and sort it into last modified time order using Vala.
I've got the directory listing part into a List < FileInfo >.
But I cannot figure out how to sort the list.
This is done via the the sort(CompareFunc<G> compare_func) method in the List class. You can read more about it here.
A basic example for strings would be:
list.sort((a,b) => {
return a.ascii_casecmp(b);
});
The return value of the function passed to sort() is the same as the ISO C90 qsort(3) function:
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
As you're interested in modify time, the FileAttribute you're looking for is TIME_MODIFIED which you would get by calling the appropriate get_attribute_* method of FileInfo.
static int main (string[] args) {
var directory = File.new_for_path ("/var/db/pkg");
var glib_list = new GLib.List<FileInfo> ();
try {
var enumerator = directory.enumerate_children (FileAttribute.TIME_MODIFIED, FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
FileInfo file_info;
while ((file_info = enumerator.next_file()) != null) {
glib_list.append(file_info);
}
} catch(Error e) {
stderr.printf ("Error: %s\n", e.message);
}
// Lets sort it.
CompareFunc<FileInfo> my_compare_func = (a, b) => {
long c = a.get_modification_time().tv_sec;
long d = b.get_modification_time().tv_sec;
return (int) (c > d) - (int) (c < d);
};
glib_list.sort(my_compare_func);
foreach (FileInfo file_info in glib_list) {
stdout.printf ("%s\n", file_info.get_name());
}
return 0;
}

Algorithm to generate all variants of a word

i would like to explain my problem by the following example.
assume the word: abc
a has variants: ä, à
b has no variants.
c has variants: ç
so the possible words are:
abc
äbc
àbc
abç
äbç
àbç
now i am looking for the algorithm that prints all word variantions for abritray words with arbitray lettervariants.
I would recommend you to solve this recursively. Here's some Java code for you to get started:
static Map<Character, char[]> variants = new HashMap<Character, char[]>() {{
put('a', new char[] {'ä', 'à'});
put('b', new char[] { });
put('c', new char[] { 'ç' });
}};
public static Set<String> variation(String str) {
Set<String> result = new HashSet<String>();
if (str.isEmpty()) {
result.add("");
return result;
}
char c = str.charAt(0);
for (String tailVariant : variation(str.substring(1))) {
result.add(c + tailVariant);
for (char variant : variants.get(c))
result.add(variant + tailVariant);
}
return result;
}
Test:
public static void main(String[] args) {
for (String str : variation("abc"))
System.out.println(str);
}
Output:
abc
àbç
äbc
àbc
äbç
abç
A quickly hacked solution in Python:
def word_variants(variants):
print_variants("", 1, variants);
def print_variants(word, i, variants):
if i > len(variants):
print word
else:
for variant in variants[i]:
print_variants(word + variant, i + 1, variants)
variants = dict()
variants[1] = ['a0', 'a1', 'a2']
variants[2] = ['b0']
variants[3] = ['c0', 'c1']
word_variants(variants)
Common part:
string[] letterEquiv = { "aäà", "b", "cç", "d", "eèé" };
// Here we make a dictionary where the key is the "base" letter and the value is an array of alternatives
var lookup = letterEquiv
.Select(p => p.ToCharArray())
.SelectMany(p => p, (p, q) => new { key = q, values = p }).ToDictionary(p => p.key, p => p.values);
A recursive variation written in C#.
List<string> resultsRecursive = new List<string>();
// I'm using an anonymous method that "closes" around resultsRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
// Recursive anonymous methods must be declared in this way in C#. Nothing to see.
Action<string, int, char[]> recursive = null;
recursive = (str, ix, str2) =>
{
// In the first loop str2 is null, so we create the place where the string will be built.
if (str2 == null)
{
str2 = new char[str.Length];
}
// The possible variations for the current character
var equivs = lookup[str[ix]];
// For each variation
foreach (var eq in equivs)
{
// We save the current variation for the current character
str2[ix] = eq;
// If we haven't reached the end of the string
if (ix < str.Length - 1)
{
// We recurse, increasing the index
recursive(str, ix + 1, str2);
}
else
{
// We save the string
resultsRecursive.Add(new string(str2));
}
}
};
// We launch our function
recursive("abcdeabcde", 0, null);
// The results are in resultsRecursive
A non-recursive version
List<string> resultsNonRecursive = new List<string>();
// I'm using an anonymous method that "closes" around resultsNonRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
Action<string> nonRecursive = (str) =>
{
// We will have two arrays, of the same length of the string. One will contain
// the possible variations for that letter, the other will contain the "current"
// "chosen" variation of that letter
char[][] equivs = new char[str.Length][];
int[] ixes = new int[str.Length];
for (int i = 0; i < ixes.Length; i++)
{
// We start with index -1 so that the first increase will bring it to 0
equivs[i] = lookup[str[i]];
ixes[i] = -1;
}
// The current "workin" index of the original string
int ix = 0;
// The place where the string will be built.
char[] str2 = new char[str.Length];
// The loop will break when we will have to increment the letter with index -1
while (ix >= 0)
{
// We select the next possible variation for the current character
ixes[ix]++;
// If we have exausted the possible variations of the current character
if (ixes[ix] == equivs[ix].Length)
{
// Reset the current character to -1
ixes[ix] = -1;
// And loop back to the previous character
ix--;
continue;
}
// We save the current variation for the current character
str2[ix] = equivs[ix][ixes[ix]];
// If we are setting the last character of the string, then the string
// is complete
if (ix == str.Length - 1)
{
// And we save it
resultsNonRecursive.Add(new string(str2));
}
else
{
// Otherwise we have to do everything for the next character
ix++;
}
}
};
// We launch our function
nonRecursive("abcdeabcde");
// The results are in resultsNonRecursive
Both heavily commented.

LINQ Next Item in List

Taking a look at my question HERE, I now want to return the next recommendation object (after) the one that matches the criteria.
So say I found item 6 out of 10, I'd like the query to return item 7 instead.
Or is there a better way?
Here's my current best method:
MyList.SkipWhile(item => item.Name != "someName").Skip(1).FirstOrDefault()
An earlier answer uses Skip(1).Take(1) which works, but returns a list of one result. In my case (and perhaps the OP's case), we're looking for the actual item. So my code skips until it gets to the one we're looking for (a Where would return a subset so we wouldn't have access to the next item) then skips one more and then gets the item.
Try this one
NEXT Item
MyList.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
PREVIOUS Item note:Reverse() will not work for LINQ to SQL
var MyList2 = MyList.ToList();
MyList2.Reverse();
MyList2.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
Since you have a List<T> object you can use its FindIndex method instead of Where to get the index of the first matching item rather than the item itself:
int index = recommendations.FindIndex(rp =>
rp.Products.Any(p => p.Product.Code == "A")
&& rp.Products.Any(p => p.Product.Code == "B")
);
Once you have the index you can get the next item or previous item or whatever you want.
How about something like this:
public static class Extension
{
public static T Next<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
bool flag = false;
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (flag) return enumerator.Current;
if(predicate(enumerator.Current))
{
flag = true;
}
}
}
return default(T);
}
}
You could then call it like you would for Where
Products.Next(x => x.Whatever);
This should do it. I haven't constructed a test for it specifically.
var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
on item1.Index equals item2.Index - 1
where item1.Rec.Products.Any(p => p.Code == "A")
&& item1.Rec.Products.Any(p => p.Code == "B")
select item2.Rec;
If you needed both records, the select statement could be
select new { MatchingItem = item1.Rec, NextItem = item2.Rec };
But then you would have to do a grouping to account for a matching item being the last item in the list (there would not be a next item in that case).
var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
on item1.Index equals item2.Index - 1
into groupjoin
from i2 in groupjoin.DefaultIfEmpty ()
where item1.Rec.Products.Any(p => p.Code == "A")
&& item1.Rec.Products.Any(p => p.Code == "B")
select new { MatchingItem = item1.Rec, NextItem = i2 == null ? null : i2.Rec };
The code I did test was something similar with a list of strings.
List<string> list = new List<string>() { "a", "b", "c", "a", "d", "a", "e" };
var query = from item1 in list.Select((s, idx) => new { Item = s, Index = idx })
join item2 in list.Select((s, idx) => new { Item = s, Index = idx })
on item1.Index equals item2.Index - 1
where item1.Item == "a"
select item2.Item;
Which returns b, d, and e.
If you are sure that:
the item is unique in the list
the item is gotten from the same list
there is the next item
you can get the next item this way
myList[myList.IndexOf(item) + 1];
// or
myList.ElementAt(myList.IndexOf(item) + 1);
If you're not sure there is the next item you can use try + catch or:
myList.ElementAtOrDefault(myList.IndexOf(item) + 1);
Is item 7 a match to your Where clause? If so, use the Skip() and Take() extension methods:
var myProducts =
from rp in recommendations
where
cp.Products.Any(p => p.Product.Code == "A") &&
cp.Products.Any(p => p.Product.Code == "B")
select rp;
var nextProduct = myProducts.Skip(1).Take(1);

Refactoring many nested ifs or chained if statements

I have an object with large number of similar fields (like more than 10 of them) and I have to assign them values from an array of variable length. The solution would be either a huge nested bunch of ifs based on checking length of array each time and assigning each field
OR
a chain of ifs checking on whether the length is out of bounds and assigning each time after that check.
Both seem to be repetitive. Is there a better solution ?
If you language has switch/case with fallthrough, you could do it like this:
switch(array.length){
case 15: field14 = array[14];
case 14: field13 = array[13];
case 13: field12 = array[12];
// etc.
case 1: field0 = array[0];
case 0: break;
default: throw Exception("array too long!");
}
for (int i = 0; i < fieldCount; i++)
fields[i].value = array[i];
That is to say, maintain an array of fields that corresponds to your array of values.
If your language supports delegates, anonymous functions, that sort of thing, you can use those to clean it up. For example, in C# you could write this:
string[] values = GetValues();
SomeObject result = new SomeObject();
Apply(values, 0, v => result.ID = v);
Apply(values, 1, v => result.FirstName = v);
Apply(values, 2, v => result.LastName = v);
// etc.
The apply method would look like:
void Apply(string[] values, int index, Action<string> action)
{
if (index < values.Length)
action(values[index]);
}
This is obviously language-dependent, but something to think about regardless.
Another very simple option that we might be overlooking is, if you are actually trying to initialize an object from this value array (as opposed to update an existing object), to just accept the default values if the array isn't large enough.
C# example:
void CreateMyObject(object[] values)
{
MyObject o = new MyObject();
o.ID = GetValueOrDefault<int>(values, 0);
o.FirstName = GetValueOrDefault<string>(values, 0);
o.LastName = GetValueOrDefault<string>(values, 0);
// etc.
}
void GetValueOrDefault<T>(object[] values, int index)
{
if (index < values.Length)
return (T)values[index];
return default(T);
}
Sometimes the dumb solution is the smartest choice.
If your fields are declared in the same order of the array's elements, you could use reflection (if available in your language) to set these values. Here is an example of how you could do it in Java:
// obj is your object, values is the array of values
Field[] fields = obj.getClass().getFields();
for (int i = 0; i < fields.length && i < values.length; ++i) {
fields[i].set(obj, values[i]);
}

Resources