Mongodb get elements inside array that appear before a particular element - arrays

I am using Mongoose in node.js to query mongoDB. I would like to retrieve all elements of an array which appear exactly before any particular array element. The element's position is not known a-priori, otherwise i would have used $slice.
E.g
My database document is like this
"user_id": "sud", "coupons": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
There are thousands of documents in my database.
var last_element = 7;
Now my query is
// HERE I WANT TO FECTH [1, 2, 3, 4, 5, 6]
// how to write this in one single query
model.findOne({"user_id": "sud"})

afaik - mongodb query don't have way to ask for element position, which is a key in your question.
As your resultset is only one document - in this case application side process is recommended and fully valid.
so using w3school example it will be like this:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple");
fruits = fruits.slice(0, a+1);

Related

Need a database for key-array storage with array specific operations like "update union" and sub-array selection

I need a database to store pairs of key - array rows like below:
===== TABLE: shoppingCart =====
user_id - product_ids
1 - [1, 2, 3, 4]
2 - [100, 200, 300, 400]
and I want to be able to update a row with new array merging to the old one while skipping duplicate values. i.e, I want operations like:
UPDATE shoppingCart SET product_ids = UNION(product_ids, [4, 5, 6]) WHERE user_id = 1
to result the first row's product_ids column to become:
[1, 2, 3, 4, 5, 6]
I also need operations like selecting a sub-array, e.g. :
SELECT product_ids[0:2] from shoppingCart
which should result:
[1,2]
any suggestions for best database for such purposes?
the arrays I need to work with are usually long (containing about 1,000 - 10,000 values of long integers ( or string version of long integers) )

How do I append values fo an observed array in RxSwift

Trying to grasp RxSwift and get stuck on a few things.
var observedData = BehaviorSubject.from([2, 3, 4, 5, 6])
.map({$0*3}).subscribe(onNext: {
print("HELLO", $0)
})
How do I append an extra value to the array, so that the subscription is triggered again?
I tried observedData.onNext and observedData.accept but they don't work.
I also would like to know the difference between
var observedData = BehaviorSubject.from([2, 3, 4, 5, 6])
and
var observedData2 = BehaviorSubject<[Int]>(value: [2, 3, 4, 5, 6])
I first assumed it was different ways of writing the same thing, but I can't use .map on observedData2
Along with the answer #EtienneJézéquel gave...
The public static func ObservableType.from(_:) function returns an Observable whereas the BehaviorSubject.init(value:) creates a BehaviorSubject which must then be converted to an Observable before you can map(_:) it.
Also, it might help to understand better when you realize you don't append to the array that is contained by the BehaviorSubject, instead you emit a new array using it. That's why Etienne's code first copies the current array out of the subject using value() throws and appends to the copy and then pushes the new array into the subject using onNext(_:).
Lastly, don't make subjects vars they should always be lets because you don't want to reseat them after setting up chains to them.
something like that should work :
let subject = BehaviorSubject<[Int]>(value: [2, 3, 4, 5, 6])
subject.asObservable().map({$0.map({$0*3})}).subscribe(onNext: { print("HELLO", $0) }).disposed(by: disposeBag)
if var value = try? subject.value() {
value.append(1)
subject.on(.next(value))
}

Is there a way I could iterate over elements in Swift while using method names?

let x = [1, 2, 2, 3, 3, 3, 1].reversed()
for element in x.method_name() {
print(element)
}
This returns
Value of type 'ReversedCollection<[Int]>' has no member 'method_name'.
Why? How do I reference the method I have created and have it do the functions I need it to do?
However, if I use the below, the problem seems to disappear. I would just like to pass in an array and do let the function do all, i.e.:
let x = Array([1, 2, 2, 3, 3, 3, 1].reversed())
Just in case you don't fully understand the motivation behind this overload of reversed returning a ReversedCollection instead of an Array, a ReversedCollection is just a "reversed view" of your original array. It is not a reversed copy of the original array. This is to save time and space, like a "lazy" collection. See this post for more details.
This is why you need the Array(...) initialiser to turn the reversed collection back into an array. You are opting out of the laziness.
On the other hand, there is another overload of reversed that returns an Array directly. Normally this overload is not selected because it is defined in a less specific type - Sequence, as opposed to Array. You need to give enough information about the type to use this overload:
let x: [Int] = [1, 2, 2, 3, 3, 3, 1].reversed()

How to get a pointer (instead of a copy) to an array in Swift?

In Swift, assigning an array to a new variable actually makes of copy. For example (as in Apple doc for Array):
var numbers = [1, 2, 3, 4, 5]
var numbersCopy = numbers
numbers[0] = 100
print(numbers)
// Prints "[100, 2, 3, 4, 5]"
print(numbersCopy)
// Prints "[1, 2, 3, 4, 5]"
How do I actually get a pointer to the same array, so modifying the elements is reflected in the same array? (The reason for this is I access in static instances of another class, e.g. "SomethingManager.sharedInstance.arrayList[aKey]" and I'll like to shorten it to an assigned pointer variable.)
(I'm interested to know how to do this in Swift 4 and 5. I don't see any existing question for Swift language.)
EDIT:
I'm providing my rationale for the need to have a pointer instead of a copy.
Say, I have the following code:
var childrenTasks = [Int64: [TaskRef]]()
defined in a class, which is accessed:
MyClass.singleton.parentTask[parentTaskID].childrenTask[taskRefID]
As you can see that the code to access childrenTask is very long. I'd like to have a pointer, just an illustration :-
var aPointerToChildrenTasks = MyClass.singleton.parentTask[parentTaskID].childrenTask[taskRefID] // I want a pointer, not a copy!
aPointerToChildrenTask.remove(at: anIndex) // if it is a pointer, I can manipulate the same set of values of the array
It will help make my code easier to read. I need a pointer to manipulate the same set of values so I use a "var". If it is only read-only, I can use a "let", but still it has performance penalty if I get a copy.
How do I get a pointer in Swift? Is this possible? (I know that in Kotlin it is possible as it is pass-by reference.)
EDIT: I see some suggestion that this question is a duplicate. No, it is not. Those other questions/answers are specifically focused on inout parameters. For my case, I just want a pointer to work in the same function/method.
Not a ‘pure’ Swift solution, but using NSArray will give you the reference semantics you desire.
NSArray is toll-free bridgeable to Array, so you can use plain as instead of as!
var numbers = [1, 2, 3, 4, 5]
var numbersCopy = numbers as NSArray
numbers[0] = 100
print(numbers)
[100, 2, 3, 4, 5]
print(numbersCopy as Array)
[1, 2, 3, 4, 5]
If you are modifying the 'copy' you will need to use a NSMutableArray.
Edit:
oops 🤭
I think I was confused by the naming of your variable numbersCopy. I see now that you want the 'copy' to share the same value as the original. By capturing the variable numbers in a block, and executing that block later, you can get the current value of numbers, and you don't need to use NSArray at all.
var numbers = [1, 2, 3, 4, 5]
var numbersCopy = {numbers}
numbers[0] = 100
print(numbers)
[100, 2, 3, 4, 5]
print(numbersCopy())
[100, 2, 3, 4, 5]
If it's just about convenience, consider making a utility function like this:
func withChildrenTasks(of parentTaskID: Int64, taskRefID: TaskRef, body: (inout [TaskRef]) -> ()) {
body(&MyClass.singleton.parentTask[parentTaskID].childrenTasks[taskRefID])
}
withChildrenTasks(of: parentTaskID, taskRefID: taskRefID) { tasks in
// do stuff with tasks
}
You can't create an "inout var", but you can always make a callback that accepts an inout parameter, so this is an easy workaround. I expect that the Swift compiler would be pretty good about optimizing it away.
If it's because you actually want to share the array reference, you will either need to wrap it in a reference type (class SharedArray<T> { var array = [T]() } might be enough for that purpose), or you could use NSMutableArray from Foundation.
Use a computed property:
var numbers = [1, 2, 3, 4, 5]
var numbersCopy: [Int] {
get { numbers }
set { numbers = newValue }
}
numbers[0] = 100
print(numbers)
// Prints "[100, 2, 3, 4, 5]"
print(numbersCopy)
// Prints "[100, 2, 3, 4, 5]"
numbersCopy[1] = 200
print(numbers)
// Prints "[100, 200, 3, 4, 5]"
print(numbersCopy)
// Prints "[100, 200, 3, 4, 5]"

Swift Array filter failing

I'm trying to filter an array for duplicates:
for i in 0...arrCheck.count-1 {
let searchNum = arrCheck[i]
let filteredArray = arrCheck.indices.filter{arrCheck[$0] == searchNum}...
if I pass something like [2, 3, 3, 4, 5, 2] this works fine. But when I pass [2, 2] it blows up - filteredArray gets millions of items. Any idea where I am falling off the rails?
Thanks

Resources