Why d3.extent without parseInt returns the max value of "9" on column num_colors on Bob Ross dataset? - d3.js

With this dataset (https://github.com/jwilber/Bob_Ross_Paintings/tree/master/data), I want to get the min and max value of the column:
num_colors.
With d3.extent() I'm able to achieve it, the values are stringify and needed to be parse first.
But why does it return "9" without parseInt.
The possible values are the following for num_colors:
1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
const dataset = await d3.csv("./bob_ross_paintings.csv")
const x1 = d => d.num_colors
console.log(d3.extent(dataset, yAccessor))
// ["1", "9"]
const x2 = d => parseInt(d.num_colors)
console.log(d3.extent(dataset, yAccessor))
// [1, 15]

Without parseInt d3.extent interprets num_colors as a string value and sorts it alphabetically

Related

How to implement stack data structure to range extraction (codewars task)?

I'm struggling with codewars kata called Range Extraction - that it takes a list of integers in increasing order and returns a correctly formatted string in the range format(overlapping seperate intervals).
Example solution:
([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]);
// returns "-6,-3-1,3-5,7-11,14,15,17-20"
Well in my solution, instead of getting -6,-3-1,3-5,7-11,14,15,17-20, I got the last item -6,1,5,11,15,20.
How can I enhance my solution? The code:
function solution(list){
let result=[]
for(let i=0;i<list.length;i++){
let e2=list[i]
let e1 = result[result.length-1]
if(e2-e1==1){
result[result.length-1]=e2
}
else{
result.push(e2 )
}
}
return result
}
console.log(solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]))
You are doing nothing to write consecutive integers in range format. Instead you are just replacing the previous result with the final item in the range which is exactly reflected in your solution:
-6: this number has no "neighbors" so is fine
1: the final item in the first range
5: the final item in the second range
...
the problem is the internal logic of the loop.
In summary, you need a while instead of an if and you need to append instead of replace:
function solution(list){
let result=[]
for(let i=0;i<list.length;i++){
//write first value in range to result
result.push(list[i].toString())
//if this is the last entry, we are done
if(i === list.length - 1){
break
}
//initialize variables
let e1 = list[i]
let e2 = list[i+1]
let isRange = false
//run thorugh array while we get consecutive numbers
while(e2-e1===1 && i < list.length-1){
//modify the OUTER LOOP index variable.
//This means when we return to the beginning of hte for loop,
// we will be at the beginning of the next range
i++
e1 = list[i]
e2 = list[i+1]
isRange = true
}
//if there were any consecutive numbers
if(isRange){
//rewrite the last entry in result as a range
result[result.length-1]+="-" + list[i].toString()
}
}
return result.toString()
}
console.log(solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]))
now, your outer loop runs through the entire array once. The inner loop will make sure the outer loop skips any items in the list that appear in a range. Finally, if the inner loop found any range at all, it will rewrite the entry as the correct range.

How to merge arrays to one array kind of respectively in ruby

I want to combine the arrays together to add the first column of all arrays, then the second columns, respectively, to the end.
My arrays :
[1,2,3,4,5]
[6,7,8,9,10]
[11,12,13,14,15]
i want result :
[1,6,11 , 2,7,12 , 3,8,13 , 4,9,14 , 5,10,15]
Suppose we have a "simple" case where the three arrays are the same length:
a = [1,2,3,4,5]
b = [6,7,8,9,10]
c = [11,12,13,14,15]
In this case, you can use Array#zip to merge the arrays in your desired way, then flatten the result into a single array:
a.zip(b, c).flatten
#=> [1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14, 5, 10, 15]
However, what if a.length > b.length or b.length > c.length?
a = [1,2,3,4,5]
b = [6,7,8,9]
c = [10,11,12]
This is a little bit harder, because now Array#zip will leave you with some nil values that you presumably want to remove:
a.zip(b, c).flatten
#=> [1, 6, 10, 2, 7, 11, 3, 8, 12, 4, 9, nil, 5, nil, nil]
a.zip(b, c).flatten.compact
#=> [1, 6, 10, 2, 7, 11, 3, 8, 12, 4, 9, 5]
And finally, what if a.length < b.length or b.length < c.length?
a = [1,2,3]
b = [4,5,6,7]
c = [8,9,10,11,12]
This is again a bit harder. Now, you'll presumably want to pad the arrays with as many nils as needed, and then perform the same operation as above:
max_length = [a,b,c].map(&:length).max
def padded_array(array, size)
array.dup.fill(nil, array.length, size)
end
padded_array(a, max_length).zip(
padded_array(b, max_length), padded_array(c, max_length)
).flatten.compact
So the complexity of your final answer depends on what arrays you are dealing with, and how far you need to go with accounting for edge cases.
a = [1,2,3,4,5]
b = [6,7,8,9,10]
c = [11,12,13,14,15]
((a.zip b).zip c).flatten.compact
=> [1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14, 5, 10, 15]

Ruby update value using detect

I have a complex data structure (multiple levels of arrays of hashes). I want to find and update a specific value. However, detect does not seem to pass the reference to the location in the data structure that I want to update. I can code this using each or each_with_object but that would iterate over ALL the data when I want to stop # the first match. In my actual program, "mymouse" and 485 are variables representing those values.
What single line command can update this entry?
Why does detect not work like each{} in terms of being able to modify the data? I would expect this to work since Ruby is pass-by-reference.
mynew = [{:mouse=>{:cat=>[485, 2, 10, 10, 10, 10, 7], :dog=>[1, 2, 3, 4, 5, 6, 7]}, :name=>"mymouse"}, {:name=>"mymouse", :mouse=>{:cat=>[485, 11, 10], :dog=>[45, 54, 65]}}]
# Finds the value I want to update to 12
puts mynew.detect{|f| f[:name] == "mymouse"}[:mouse][:cat].detect{|x| x==485}
# results in an error
mynew.detect{|f| f[:name] == "mymouse"}[:mouse][:cat].detect{|x| x==485} = 12
# Does not update the value to 12
location = mynew.detect{|f| f[:name] == "mymouse"}[:mouse][:cat].detect{|x| x==485}
location = 12
puts mynew # Value unchanged
Here is one way to do it:
data = [
{
:name=>"mymouse",
:mouse=>{
:cat=>[485, 2, 10, 10, 10, 10, 7],
:dog=>[1, 2, 3, 4, 5, 6, 7]
},
},
{
:name=>"othermouse",
:mouse=>{
:cat=>[485, 11, 10],
:dog=>[45, 54, 65]
}
}
]
entry = data.find { |f| f[:name] == "mymouse" }
array = entry[:mouse][:cat]
modified_array = array.map { |n| n == 485 ? 12 : n }
entry[:mouse][:cat] = modified_array
require 'pp'
pp data
This will work; I tested it.
Alternatively, once you have the array you could just use:
array[array.index(485)] = 12
This modifies the original array, so it could have a different effect than the main solution I posted, which does not modify the original array.

For Loop in Apple Swift

Apple's newly released language Swift has an example on the official documentation. Example is like this;
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
This is pretty simple but as an extra exercise,it requires to add another variable in order to return what type is the largest number (i.e. Square is the case here)
However, I can't seem to figure out what is "(kind,numbers)" here represent and how should I make my for-loop to go through all Dictionary(interestingNumbers) keys and find which key has the largest number.
Thank you all for your help in advance
Swift allows you to loop over a dictionary with tuple-syntax (key, value). So in every iteration of the for-loop Swift cares about reassigning the specified tuple-variables (kind and number in your case) to the actual dictionary-record.
To figure out which Key includes the highest number in your example you can extend your code as follows:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var largestKey = ""
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
largestKey = kind
}
}
}
largest // =25
largestKey // ="Square"
Or if you want to practice the tuple-syntax try that (with the same result):
var largest = 0
var largestKey = ""
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
(largestKey, largest) = (kind, number)
}
}
}
largest // =25
largestKey // ="Square"
I can't seem to figure out what is "(kind,numbers)" here represents
It's a key-value pair (a tuple) containing the kind of the number. This syntax is called decomposition, basically, inside the loop you can access kind as the kind and numbers as the numbers that map for it.
For example, in some iteration:
kind // "Prime"
numbers // [2, 3, 5, 7, 11, 13]
Quoting the guide:
You can also iterate over a dictionary to access its key-value pairs. Each item in the dictionary is returned as a (key, value) tuple when the dictionary is iterated, and you can decompose the (key, value) tuple’s members as explicitly named constants for use within in the body of the for-in loop.
for (kind, numbers) in interestingNumbers{}
This for loop actually enumerating the key/value pairs of dictionary interestingNumbers. Where kind is the key and numbers is the correspoding value
kind:Prime //Key
numbers: [2, 3, 5, 7, 11, 13] //Value
Here the complete solution of the exercise
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var type: String = ""
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
type = kind
}
}
}
largest
type
However, I can't seem to figure out what is "(kind,numbers)" here represent
The loop iterates over the dictionary, and every iteration gives you a key and associated value. Those are called kind (key) and numbers (value) here. You can choose any name you want.
and how should I make my for-loop to go through all Dictionary(interestingNumbers) keys and find which key has the largest number.
You get each key in turn in the kind loop variable.
Once you find one that results in a new largest, you can assign that to a result variable, say largestKind.
At the end of the loop, largestKind will contain the key of the array with the largest number (that number being the largest you already have).
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
This will return pair of (String,Int) which we have in Our Dictionary
similar to function return multiple value as below,
func refreshWebPage() -> (status:String,code:Int){
//refresh logic
return ("Success",200)
}

LINQ: Get min and max values of sequence of numbers divided into subsequences

how can I split a sequence of numbers into subgroups of numbers and get the local minimum and maximum of the subgroups with linq?
If I have a sequence of, lets say 11 items { 3, 2, 5, 9, 9, 6, 7, 2, 5, 11, 2 }
I want to split this into subgroups with 3 or less items.
So I get the following 4 subgroups: { 3, 2, 5 } , { 9, 9, 6 } , { 7, 2, 5} , { 11, 2}
The final return values of the LinQ expression (getting min and max for each group) should be 2, 5, 6, 9, 2, 7, 2, 11
TIA,
Sascha
This should do it.
var numbers = new[] { 3, 2, 5, 9, 9, 6, 7, 2, 5, 11, 2 };
var query = from p in numbers.Select((n, i) => new { n, Group = i / 3 })
group p.n by p.Group into g
from n in new[] { g.Min(), g.Max() }
select n;
Well, using MoreLINQ's Batch method to do the grouping, you could use:
var query = source.Batch(3, batch => new[] { batch.Min(), batch.Max() })
.SelectMany(x => x);

Resources