Sort by array index using Realm and NSPredicate - nspredicate

I have an array of IDs: [INT]. Now I want to select all the objects have these ids but need to follow the order of id in the IDs array.
let IDs = [2, 6, 3, 4, 10, 9]
let predicate = NSPredicate(format: "id IN %#", IDs)
let objects = realm.objects(Item.self).filter(predicate)
But in the end, objects was ordered in a different way with IDs. Is there any way that I can sort this objects to the correct order?

You can do it using sort():
let IDs = [2, 6, 3, 4, 10, 9]
let predicate = NSPredicate(format: "id IN %#", IDs)
do {
let realm = try Realm()
let objects = realm.objects(Item).filter(predicate).sort({ IDs.indexOf($0.id) < IDs.indexOf($1.id) })
} catch {
}

In Realm, Results conforms to the RealmCollectionType protocol, which has a sorted(_:) member function. This function takes a sequence of SortDescriptors, which are StringLiteralConvertible, making them pretty easy to use:
let realm = try! Realm()
let IDs = [2, 6, 3, 4, 10, 9]
let objects = realm.objects(Item).filter("id IN %#", IDs).sorted(["id"])

Related

best practice to check if a collection has duplicate values?

what is the best practice to check if a collection has duplicate values. example:
$collection = collect([1, 2, 3, 4, 5]);
$collection->isDuplicate() // false
$collection = collect([1, 2, 2, 4, 5]);
$collection->isDuplicate() // true
You can use
$collection->duplicates()->isNotEmpty(); to check if there are duplicates.

How to get the indices that would sort a Vec?

I want to get the indices that would sort a Vec in Rust. Effectively, I want argsort() from numpy.
For example:
let v = vec![1, 7, 4, 2];
let i = argsort(&v);
assert_eq!(i, &[0, 3, 2, 1]);
Not sure if there's something pre-made for this, but its simple enough to implement yourself with .sort_by_key():
pub fn argsort<T: Ord>(data: &[T]) -> Vec<usize> {
let mut indices = (0..data.len()).collect::<Vec<_>>();
indices.sort_by_key(|&i| &data[i]);
indices
}
See it working on the playground.

Is it possible to get non-contiguous slices from an ndarray?

Is it possible to index columns in a Rust ndarray matrix using a Vec rather than a Slice object? The only documentation I can find pertains to slicing using contiguous columns
Specifically, I am trying to implement something like the following code in Python:
x = np.array([[1,2,3,4,5,6], [7,8,9,10,11,12]])
idx = [0,1,2,4]
x[:, idx]
The outcome of x[:, idx] would be the subset of the matrix containing all rows and only columns described in idx, i.e., [0,1,2,4].
I am currently using ndarray (as the title suggests) but I cannot find a way to subset on non-contiguous slices. For instance, you can pass ndarray, which can take a Slice with a start, stop and an index, but I cannot find a way to pass a list of columns that cannot be described using a Slice object.
For instance:
#[macro_use]
extern crate ndarray;
fn main() {
let mut x = array![[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]];
let idx = vec![0, 1, 2, 4];
// The following works as expected
let y = x.slice(s![.., 0..2]);
println!("{:?}", y);
// This is conceptually what I would like to do but
// It does not work.
let y = x.slice(s![.., idx]);
}
The analogue of "advanced indexing" in Numpy is the ArrayBase::select() method:
use ndarray::{array, Axis};
fn main() {
let x = array![[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]];
let idx = vec![0, 1, 2, 4];
println!("{}", x.select(Axis(1), &idx));
}
producing the output
[[1, 2, 3, 5],
[7, 8, 9, 11]]
Note that the resulting array is a copy of the selected elements (just as it is in Numpy). Depending on your use case, you may not need the copy; it's possible you can make do with just iterating over idx and using x.slice(s![.., i]) for all i in idx.

Find vector of unique elements and vector of repeats using for loops and if conditions

I want a program that takes a vector of integers and creates two new vectors, one which contains each unique element, and another which contains the number of times these unique elements were repeated in the original vector.
So,
[1, 2, 2, 3, 3, 3]
has unique elements:
[1, 2, 3]
with the following number of repeats:
[1, 2, 3]
I know this has been asked before, but I want to achieve this using purely for loops and if conditions if need be. For the same reason, the code can be given in pseudocode obviously.
Please be nice, I am literally a beginner who learned programming syntax a few days ago.
Here a solution
var arr = [1, 2, 2, 2, 3, 3, 3, 3]
var unique = [...new Set(arr)]
var repeated = []
var i = 0
unique.map((a) => {
arr.map((b) => {
if(a === b) i++
})
repeated.push(i)
i = 0
})
console.log("[" + arr.join(",") + "] has unique elements [" + unique.join(",") + "] with the following number of repeats [" + repeated.join(",") + "]")

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)
}

Resources