Iterating Through a Dictionary in Swift - dictionary

I am a little confused on the answer that Xcode is giving me to this experiment in the Swift Programming Language Guide:
// Use a for-in to iterate through a dictionary (experiment)
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
I understand that as the dictionary is being transversed, the largest number is being set to the variable, largest. However, I am confused as to why Xcode is saying that largest is being set 5 times, or 1 time, or 3 times, depending on each test.
When looking through the code, I see that it should be set 6 times in "Prime" alone (2, 3, 5, 7, 11, 13). Then it should skip over any numbers in "Fibonacci" since those are all less than the largest, which is currently set to 13 from "Prime". Then, it should be set to 16, and finally 25 in "Square", yielding a total of 8 times.
Am I missing something entirely obvious?

Dictionaries in Swift (and other languages) are not ordered. When you iterate through the dictionary, there's no guarantee that the order will match the initialization order. In this example, Swift processes the "Square" key before the others. You can see this by adding a print statement to the loop. 25 is the 5th element of Square so largest would be set 5 times for the 5 elements in Square and then would stay at 25.
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 {
println("kind: \(kind)")
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
This prints:
kind: Square
kind: Prime
kind: Fibonacci

let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }
Result would be
("FirstName", "Maninder")
("LastName", "Singh")
("Address", "Chandigarh")

This is a user-defined function to iterate through a dictionary:
func findDic(dict: [String: String]) {
for (key, value) in dict {
print("\(key) : \(value)")
}
}
findDic(dict: ["Animal": "Lion", "Bird": "Sparrow"])
// prints…
// Animal : Lion
// Bird : Sparrow

If you want to iterate over all the values:
dict.values.forEach { value in
// print(value)
}

Here is an alternative for that experiment (Swift 3.0). This tells you exactly which kind of number was the largest.
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 whichKind: String? = nil
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
whichKind = kind
largest = number
}
}
}
print(whichKind)
print(largest)
OUTPUT:
Optional("Square")
25

You can also use values.makeIterator() to iterate over dict values, like this:
for sb in sbItems.values.makeIterator(){
// do something with your sb item..
print(sb)
}
You can also do the iteration like this, in a more swifty style:
sbItems.values.makeIterator().forEach{
// $0 is your dict value..
print($0)
}
sbItems is dict of type [String : NSManagedObject]

Related

Remove elements of vector in a loop based on index

Let's say I have a vector, the values are from 1 to 10. I want that if you find 5 and 5 next to each other, remove them together with the next elements.
input
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10]
expected output
[1, 2, 3, 4]
This was my attempt. I'm finding index to remove, but borrowing rules are making me stuck.
let mut element = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
for (index, val) in element.iter().enumerate() {
if *val == 5 {
if let Some(next_val) = element.get(index + 1) {
if *next_val == 5 {
//element.drain(index..);
}
}
}
}
Rust is saving you from iterator invalidation (a common source of bugs in other languages). This is an error that usually happens when you try to modify a data structure while concurrently iterating over it. You cannot move on to the (now-deleted) next element after calling element.drain(index..). So you need to add a break after that point to avoid memory unsafety.
In this case just adding break; is sufficient to make the code compile. However, for a more concise, linear solution, take full advantage of the iterators and methods provided by the standard library:
if let Some(index) = element.windows(2).position(|pair| pair[0] == pair[1]) {
element.truncate(index);
}
windows(2) on a slice gives an iterator over subslices of length 2, and the position call returns the index of the first element of that iterator for which the two elements of the slice are equal. (If no such pair exists, position returns None.)
I find that the position closure becomes more obvious with the (currently unstable) array_windows feature:
if let Some(index) = element.array_windows().position(|[x, y]| x == y) {
element.truncate(index);
}
Playground
Related
is it possible to filter on a vector in-place?
You can't do what you want to do because you want to remove some elements from a vector while you are iterating it. And this is a big mistake. Note that removing any elements from a vector invalidates the iterators, hence you will access unexpected locations so rust doesn't allow UBs
You can use something like the following
let mut elements = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
let mut first_repeated_five_index_op = None;
for index in 0..elements.len()-1{
if elements[index] == 5 && elements[index + 1] == 5{
first_repeated_five_index_op = Some(index);
break;
}
}
if let Some(first_repeated_five_index) = first_repeated_five_index_op{
elements.truncate(first_repeated_five_index);
}
println!("{:?}", elements);
See a Demo

Interleaving Elements of a Prolog list

I am new to Prolog and came across this practice excercise. The question asks to define a predicate
zipper([[List1,List2]], Zippered). //this is two lists within one list.
This predicate should interleave elements of List1 with elements of List2.
For example,
zipper([[1,3,5,7], [2,4,6,8]], Zippered) -> Zippered = [1,2,3,4,5,6,7,8].
zipper([[1,3,5], [2,4,6,7,8]], Zippered) -> Zippered = [1,2,3,4,5,6,7,8].
So far I have a solution for two different list:
zipper ([],[],Z).
zipper([X],[],[X]).
zipper([],[Y],[Y]).
zipper([X|List1],[Y|List2],[X,Y|List]) :- zipper(List1,List2,List).
I am not sure how I can translate this solution for one list. Any suggestion on where I can start would be greatly helpful!
Firstly you should change zipper ([],[],Z). to zipper ([],[],[]).. Then to make it work for one list you could do what mat recommended in the comment or you could change it a little. So my version is:
zipper([],[],[]).
zipper([X,[]],X).
zipper([[],Y],Y).
zipper([[X|List1],[Y|List2]],[X,Y|List]) :- zipper([List1,List2],List).
And for your examples:
?- zipper([[1,3,5,7], [2,4,6,8]], Zippered).
Zippered = [1, 2, 3, 4, 5, 6, 7, 8] ;
Zippered = [1, 2, 3, 4, 5, 6, 7, 8] ;
false.
?- zipper([[1,3,5],[2,4,6,7,8]],Zippered).
Zippered = [1, 2, 3, 4, 5, 6, 7, 8] ;
false.

How to remove\replace big bracket while printing List or array in groovy?

I have to give list of values into in clause of SQL query but while retrieving the values [ ] also come along with data which is not readable by query language.
For example I have list as:
def val = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8))
while doing println(val) output come as [1, 2, 3, 4, 5, 6, 7, 8] but in the query it is needed as: 1, 2, 3, 4, 5, 6, 7, 8
In java this one works as System.out.println(val.toString().replaceAll("[\\[\\]]", "")) but not in groovy. Can't we use collection to remove like this?
Instead of:
def val = new ArrayList(Arrays.asList(1,2,3,4,5,6,7,8))
use:
def val = new ArrayList(Arrays.asList(1,2,3,4,5,6,7,8)).join(', ')
or simply:
def val = [1,2,3,4,5,6,7,8].join(', ')
Try using g-strings and the minus operator:
println "${val}" - '[' - ']'

plotting an array of dataset with ListPlot Mathematica

I have a set of datapoints such as (THIS IS AN EXAMPLE)
val=4; (*this value is calculated before in the program, so it not known a priori*)
x={0,1,2,3};
data=Table[0, {val}];
data[[1]] = {1,5,6,8};
data[[2]] = {9,7,1,3};
data[[3]] = {3,4,5,6};
data[[4]] = {2,2,4,6};
Now I can plot each of these data with ListPlot as
ListPlot[Transpose[{x,data[[1]]}]]
and if I want to plot more than one I can do
ListPlot[{Transpose[{x, data[[1]]}], Transpose[{x, data[[2]]}]}]
but how can I plot all of them in one code single line, by considering that val is calculated before in the program?
Is there a way to do something like
For[i = 1, i < val + 1, i++, ListPlot[Transpose[{x,data[i]}]]......]
having a single graph with all x-y curves?
Indeed I would like a static picture of
Manipulate[ListPlot[Transpose[{x, data[[i]]}]], {i, 1, val,1}]
Thanks
Virgilio
You want to "do the same thing" to every element of a list. That should tell you to think of using Map. Your list is named data and each element is your four element sublist. If you look at the help page for Map it shows you need to think up a function that does what you need to do to each individual sublist. You have already understood that you need to use Transpose with x and your sublist so that tells you your function and you are almost there. The result of Map will be a list of all those results. So
In[1]:= x = {0, 1, 2, 3};
data = {{1, 5, 6, 8}, {9, 7, 1, 3}, {3, 4, 5, 6}, {2, 2, 4, 6}};
ListPlot[Map[Transpose[{x, #}] &, data], Joined -> True]
Out[3]= ...FourOverlaidPlotsSnipped...
Go through that a word at a time until you can really understand the thinking that was done to be able to write that. You will use this idea again and again if you keep using Mathematica.
For the example you give the cleanest method is to use DataRange:
data = {{1, 5, 6, 8}, {9, 7, 1, 3}, {3, 4, 5, 6}, {2, 2, 4, 6}};
ListLinePlot[data, DataRange -> {0, 3}]
Please ask your future questions on the dedicated Mathematica StackExchange site:

Converting Array of Arrays to Backbone Collection of Models

new to Backbone and underscore js here.
I have an array of arrays that I want to convert to a collection of models.
So it's like
{ {1, 2, 3, 4}, {5, 6, 7, 8}}
The second level of arrays is what's going into a backbone model. Right now, I have
collection.reset(_.map(results, (indvidualResults) -> new model(individualResults))
Which doesn't work as when I do a console.log(collection.pop) I get a function printed out. I think this is because I'm working with an array of arrays (but I could be wrong). How do I convert the second array into a model and then put that into a collection?
Reshape your raw data to look more like:
[{ first: 1, second: 2, third: 3, fourth: 4 }, { first: 5, second: 6, third: 7, fourth: 8}]
Assuming you have a model and collection defined something like:
var Model = Backbone.Model.extend({});
var Collection = Backbone.Collection.extend({
model: Model
});
Then just pass the array of attribute hashes into the reset method:
var results = [{ first: 1, second: 2, third: 3, fourth: 4 }, { first: 5, second: 6, third: 7, fourth: 8}];
var collection = new Collection();
collection.reset(results);
var model = collection.pop();
console.log(JSON.stringify(model.toJSON());

Resources