use recursive function to generate combination in Swift - swift

I have five arrays. I can use five for-loop to generate the result, but I need a recursive function so that I can generate the combinations from more arrays. How do I use a recursive function to generate the combinations? Each combination includes one element from the five arrays.

I'm not sure why you need it to be recursive, but there are a few ways to do it, anyway. You can use higher-order functions to make an Array extension that does what you want:
extension Array {
func everyOf<S: SequenceType where S.Generator.Element == T>(ar: S...) -> [[T]] {
return ar.reduce(self.map{[$0]}){
perms, items in perms.flatMap {
perm in Swift.map(items){ perm + [$0] }
}
}
}
}
This would work like:
[1, 2].everyOf([3, 4]) //[[1, 3], [1, 4], [2, 3], [2, 4]]
or:
[1, 2].everyOf([3, 4], [5, 6])
//[
// [1, 3, 5],
// [1, 3, 6],
// [1, 4, 5],
// [1, 4, 6],
// [2, 3, 5],
// [2, 3, 6],
// [2, 4, 5],
// [2, 4, 6]
//]
But the different arrays don't have to be the same length:
[1, 2].everyOf([3], [5, 6]) // [[1, 3, 5], [1, 3, 6], [2, 3, 5], [2, 3, 6]]
And you can do it as a non-method as well:
func everyOf<T>(ar: [[T]]) -> [[T]] {
return dropLast(ar).reduce(ar.last!.map{[$0]}){
perms, items in perms.flatMap{
perm in Swift.map(items){ perm + [$0] }
}
}
}
everyOf([[1, 2], [3, 4]]) // [[3, 1], [3, 2], [4, 1], [4, 2]]
If you're really into the 'aul recursion, though, here you go:
func everyOf<T>(seqs: [[T]]) -> [[T]] {
return last(seqs).map {
fSeq in everyOf(Array(dropLast(seqs))).flatMap {
seq in fSeq.map{ seq + [$0] }
}
} ?? [[]]
}
everyOf([[1, 2], [3, 4]]) // [[3, 1], [3, 2], [4, 1], [4, 2]]

Related

Using map in spark to make dictionary format

I executed the following code:
temp = rdd.map( lambda p: ( p[0], (p[1],p[2],p[3],p[4],p[5]) ) ).groupByKey().mapValues(list).collect()
print(temp)
and I could get data:
[ ("A", [("a", 1, 2, 3, 4), ("b", 2, 3, 4, 5), ("c", 4, 5, 6, 7)]) ]
I'm trying to make a dictionary with second list argument.
For example I want to reconstruct temp like this format:
("A", {"a": [1, 2, 3, 4], "b":[2, 3, 4, 5], "c":[4, 5, 6, 7]})
Is there any clear way to do this?
If I understood you correctly you need something like this:
spark = SparkSession.builder.getOrCreate()
data = [
["A", "a", 1, 2, 5, 6],
["A", "b", 3, 4, 6, 9],
["A", "c", 7, 5, 6, 0],
]
rdd = spark.sparkContext.parallelize(data)
temp = (
rdd.map(lambda x: (x[0], ({x[1]: [x[2], x[3], x[4], x[5]]})))
.groupByKey()
.mapValues(list)
.mapValues(lambda x: {k: v for y in x for k, v in y.items()})
)
print(temp.collect())
# [('A', {'a': [1, 2, 5, 6], 'b': [3, 4, 6, 9], 'c': [7, 5, 6, 0]})]
This is easily doable with a custom Python function once you obtain the temp object. You just need to use tuple, list and dict manipulation.
def my_format(l):
# get tuple inside list
tup = l[0]
# create dictionary with key equal to first value of each sub-tuple
dct = {}
for e in tup[1]:
dct2 = {e[0]: list(e[1:])}
dct.update(dct2)
# combine first element of list with dictionary
return (tup[0], dct)
my_format(temp)
# ('A', {'a': [1, 2, 3, 4], 'b': [2, 3, 4, 5], 'c': [4, 5, 6, 7]})

Flutter sort List with value of a list by value of List Within List

Basically, I have a list of scores and their corresponding index. I want to sort "scores" by a value within that list.
scores = [[0, 340], [1, 69], [2, 485], [3, 194], [4, 91], [5, 130], [6, 110], [7, 655], [8, 45], [9, 445], [10, 34], [11, 385]]
I want to sort the list by the second value within that list. The end result should be something like:
scores = [[10,34], [8,45], [1,69].....]
scores.sort(); gives an error saying List is non-comparable
Thanks, Mason
void main() {
var scores = [[0, 340], [1, 69], [2, 485], [3, 194], [4, 91], [5, 130], [6, 110], [7, 655], [8, 45], [9, 445], [10, 34], [11, 385]];
print(scores);
scores.sort((a,b) => a[1].compareTo(b[1]));
print(scores);
}
Result:
[[10, 34], [8, 45], [1, 69], [4, 91], [6, 110], [5, 130], [3, 194], [0, 340], [11, 385], [9, 445], [2, 485], [7, 655]]

How to split `NSmutableArray` array array to chunks swift 3?

NSMutableArray *sample;
I have an NSmutableArray, and I want to split it into chunks. I have tried checking the internet didn't find the solution for it. I got the link to split integer array.
How about this which is more Swifty?
let integerArray = [1,2,3,4,5,6,7,8,9,10]
let stringArray = ["a", "b", "c", "d", "e", "f"]
let anyObjectArray: [Any] = ["a", 1, "b", 2, "c", 3]
extension Array {
func chunks(_ chunkSize: Int) -> [[Element]] {
return stride(from: 0, to: self.count, by: chunkSize).map {
Array(self[$0..<Swift.min($0 + chunkSize, self.count)])
}
}
}
integerArray.chunks(2) //[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
stringArray.chunks(3) //[["a", "b", "c"], ["d", "e", "f"]]
anyObjectArray.chunks(2) //[["a", 1], ["b", 2], ["c", 3]]
To Convert NSMutableArray to Swift Array:
let nsarray = NSMutableArray(array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
if let swiftArray = nsarray as NSArray as? [Int] {
swiftArray.chunks(2) //[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
}
If you wanna insist to use NSArray, then:
let nsarray = NSMutableArray(array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
extension NSArray {
func chunks(_ chunkSize: Int) -> [[Element]] {
return stride(from: 0, to: self.count, by: chunkSize).map {
self.subarray(with: NSRange(location: $0, length: Swift.min(chunkSize, self.count - $0)))
}
}
}
nsarray.chunks(3) //[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
You can use the subarray method.
let array = NSArray(array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
let left = array.subarray(with: NSMakeRange(0, 5))
let right = array.subarray(with: NSMakeRange(5, 5))

One trendline for multiple series

Hello I have this simple example with 2 data series and 2 trendiness.
http://jsfiddle.net/ttwqazav/
I want to have only 1 trendline for both of them, as an average! Is that possible?
google.load('visualization', '1.1', {packages: ['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['X', 'Y', 'Z'],
[0, 0, 2],
[1, 2, 4],
[2, 4, 5],
[3, 6, 8],
[4, 8, 10],
[5, 10, 12],
[6, 12, 14],
[7, 14, 16],
[8, 16, 18],
[9, 18, 20],
[10, 20, 22]
]);
var options = {
height: 500,
legend: 'none',
colors: ['#9575cd', '#33ac71'],
pointShape: 'diamond',
trendlines: {
0: {
color:'red',
type: 'linear',
pointsVisible: false
}
}
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
chart.draw(data, options);
}
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
Just specify data points as below:
var data = google.visualization.arrayToDataTable([
['X', 'Y'],
[0, 0],
[1, 2],
[2, 4],
[3, 6],
[4, 8],
[5, 10],
[6, 12],
[7, 14],
[8, 16],
[9, 18],
[10, 20],
[0, 2],
[1, 4],
[2, 5],
[3, 8],
[4, 10],
[5, 12],
[6, 14],
[7, 16],
[8, 18],
[9, 20],
[10, 22]
]);
But you cannot differentiate between the two sets of data points!
If your aim is to get average best fit line, it'll work. :)

show percentages and Numbers both in a Stack Flot Chart

I try to create a bar chart with percentage numbers on each bar number.
the following is my code, I want the Percentage to be shown in bar Numbers, also Count of each item in the tool tip (vise versa) .
I've tried stackedpercent but it didn't work.
For example these are my percentage values for data:
var dc20 = [[37, 0], [0, 1], [16, 2], [34, 3]];
var dc21 = [[58, 0], [0, 1], [80, 2], [62, 3]];
var dc22 = [[0, 0], [0, 1], [0, 2], [0, 3]];
var dc23 = [[5, 0], [100, 1], [4, 2], [4, 3]];
var dc24 = [[0, 0], [0, 1], [0, 2], [0, 3]];
and these values are for Count of records
var dc20 = [[16, 0], [0, 1], [5, 2], [11, 3]];
var dc21 = [[25, 0], [0, 1], [25, 2], [20, 3]];
var dc22 = [[0, 0], [0, 1], [0, 2], [0, 3]];
var dc23 = [[2, 0], [1, 1], [1, 2], [1, 3]];
var dc24 = [[0, 0], [0, 1], [0, 2], [0, 3]];
Update
This is the Fiddle link for that.
The simplest solution is to add the counts as a seperate array:
var counts = [
[16, 0, 5, 11],
[25, 0, 25, 20],
[0, 0, 0, 0],
[2, 1, 1, 1],
[0, 0, 0, 0]
];
and use that in the tooltipOpts:
content: function (label, xval, yval, flotItem) {
return '%' + xval + 'which has ' + counts[flotItem.seriesIndex][flotItem.dataIndex] + ' records ';
},
See the updated fiddle.