How to remove multiple items from a swift array? - swift

For example i have an array
var array = [1, 2, 3, 4]
I want to remove item at index 1 then at index 3 "let it be in a for loop".
But removing the item at index 1 will move the item at index 3 to index 2, thus messing up the second removal.
Any suggestions ?

Given your array
var numbers = [1, 2, 3, 4]
and a Set of indexes you want to remove
let indexesToRemove: Set = [1, 3]
You want to remove the values "2" and "4".
Just write
numbers = numbers
.enumerated()
.filter { !indexesToRemove.contains($0.offset) }
.map { $0.element }
Result
print(numbers) // [1, 3]

It's simple. delete items from the end.
First delete 3 and after that delete 1

Swift 3: Use swift closure to perform the same operation.
If your array is like
var numbers = [0, 1, 2, 3, 4, 5]
and indexes you want to remove
let indexesToBeRemoved: Set = [2, 4]
numbers = numbers
.enumerated()
.filter { !indexesToRemove.contains($0.offset) }
.map { $0.element }
and result
print(numbers) // [0, 1, 3, 5]
Swift 3:
Here is same operation with JSON Object (dictionary)
var arrayString = [
[ "char" : "Z" ],
[ "char" : "Y" ],
[ "char" : "X" ],
[ "char" : "W" ],
[ "char" : "V" ],
[ "char" : "U" ],
[ "char" : "T" ],
[ "char" : "S" ]
]
let arrayIndex = [2, 3, 5]
arrayString = arrayString.enumerated()
.filter { !arrayIndex.contains($0.0 + 1) }
.map { $0.1 }
print(arrayString)
[["char": "Z"], ["char": "W"], ["char": "U"], ["name": "T"], ["name":
"S"]]

Related

How to use $in operator with pair of attributes

Consider this collection
/* 1 */
{
"key" : 1,
"b" : 2,
"c" : 3
}
/* 2 */
{
"key" : 2,
"b" : 5,
"c" : 4
}
/* 3 */
{
"key" : 3,
"b" : 7,
"c" : 9
}
/* 4 */
{
"key" : 4,
"b" : 7,
"c" : 4
}
/* 5 */
{
"key" : 5,
"b" : 2,
"c" : 9
}
I want to use the $in operator and write a query to return the document such (b, c) IN ((2, 3), (7, 9)). It means "return all rows where b is 2 and c is 3 at the same time, OR b is 7 and с is 9 at the same time."
How can I use $in operator to use multiple attribute values.
If I use the following query
db.getCollection('test').find({
$and:[
{b:{$in:[2,7]}},
{c:{$in:[3,9]}}
]
})
then I get following results
(2,3)
(7,9)
(2,9) --> This is unwanted record.
IN SQL world it is possible
SELECT *
FROM demo
WHERE (b, c) IN ((2, 3), (7, 9))
What is the equivalent in Mongo DB?
If I get it right, the thing you are doing is getting all the pairs (2,3),(2,9),(7,3),(7,9).
But you want to match those one by one, so your valid pairs should be (2, 3), (7, 9). To satisfy this, you can match b and c one by one, pair them and "or" them after.
db.getCollection('test').find({
$or: [
{$and: [ {b : 2}, {c : 3} ]},
{$and: [ {b : 7}, {c : 9} ]}
]
})

query for indexed key values that has the most references?

We have a very big collection, with several indexes.
Since an index is basically a table with the indexed field as key, and a list of ObjectIDs as value, we were wondering if we could somehow get the key that has the highest number of Objects it points to.
For example, if we have a collection:
{ _id: 1, a : 1, b : 1 },
{ _id: 2, a : 2, b : 2 },
{ _id: 3, a : 2, b : 3 },
{ _id: 4, a : 2, b : 4 },
{ _id: 5, a : 3, b : 4 },
{ _id: 6, a : 3, b : 4 },
{ _id: 7, a : 4, b : 4 }
Where there's an index of "a".
I assume there a table somewhere that looks like this:
index a:
"1" => [ 1 ],
"2" => [ 2, 3, 4 ],
"3" => [ 5, 6 ],
"4" => [ 7 ]
In which case we'd like to somehow query for the index value with the longest list of objects - "2".
Is something like that possible in MongoDB?
The answer is no.
Actually, indexes don't have a list of document objectId's, just pointers to the data. To get document's objectId, system must go to the disk to read it. That's why, if you have a index what can answer to your query and you don't need _id in your result, remember always project {_id:0, key1:1, key2:1, keyX:1} so result can be returned from index and there is no need to go to the disk.

How can create assoc 3D Array of Array?

I tried create Array 3D but i still don't know how to create one ?
var array = [
"10001": [
"last_index": 0, //Int
"conteiner": [
"id_from": 321, // Int
"val2": "string text" // String
]
]
]
This works for me in Swift 2.0:
let array : [String : [String : Any]] = [
"10001": [
"last_index": 0, //Int
"conteiner": [
"id_from": 321 as Any, // Int
"val2": "string text" as Any // String
]
]
]
array["10001"]?["last_index"] // 0

Mongo: Array field has no values in given array?

I'm trying to write up a mongo query that finds all entries where the "steps" field has no values within an array argument.
So for example, given two entries with values:
Entry1:
steps: [3, 4]
Entry2:
steps: [3, 5]
The query should return entry1, but not entry 2, for input array [4, 8, 10]. I'm quite new to mongo - any ideas appreciated.
You mean you have some records:
db.foo.find()
{ "_id" : 1, "steps" : [ 3, 4 ] }
{ "_id" : 2, "steps" : [ 3, 5 ] }
Then you would query:
> db.foo.find({steps:{$in:[4,8,10]}})
{ "_id" : 1, "steps" : [ 3, 4 ] }
the $in clause will pick records in which any stored element matches any of terms in the array supplied in the query

Mongodb -how to find records that contain certain keywords array

Recently I wanted to filter out records that contain a certain keyword array in MongoDB, for example: I have five records that contain keywords array:
{a:[1,2]}
{a:[1,3,8]}
{a:[1,2,5]}
{a:[3,5,1]}
{a:[4,5]}
If I input the array [1,2,3,5] for search, then I want to get:
{a:[1,2]}
{a:[1,2,5]}
{a:[3,5,1]}
Each of them is a sub array of [1,2,3,5].
Any idea?
Please don't use a where clause (when possbile). Thanks!
Its simple to do in mongodb, but the harder part is preparing the data for the query. Let me explain that in oder
Simple part
You can use $in to find the matching elements in an array. Let us try
db.coll.find({a:{$in:[1,2,3,5]})
and the result is
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42439ed13aa728e9efc"), "a" : [ 1, 3, 8 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
{ "_id" : ObjectId("4f37c43439ed13aa728e9efe"), "a" : [ 3, 5, 1 ] }
{ "_id" : ObjectId("4f37c43e39ed13aa728e9eff"), "a" : [ 4, 5 ] }
ohh, its not the result we expected. Yes because $in return an item if any matching element found (not necessarily all).
So we can fix this by passing the exact array elements to $in, for example if we want to find the items matching these exact arrays {a:[1,2]} {a:[1,2,5]} and {a:[4,5,6]}
db.coll.find({a:{$in:[[1,2],[1,2,5],[4,5,6]]}})
you will get
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
Thats all
Hardest part
The real hardest part is forming all the possible combination of your input array [1,2,3,5]. You need to find a way to get all the combination of the source array (from your client) and pass it to $in.
For example, this JS method will give you all the combinations of the given array
var combine = function(a) {
var fn = function(n, src, got, all) {
if (n == 0) {
if (got.length > 0) {
all[all.length] = got;
}
return;
}
for (var j = 0; j < src.length; j++) {
fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
}
return;
}
var all = [];
for (var i=0; i < a.length; i++) {
fn(i, a, [], all);
}
all.push(a);
return all;
}
>> arr= combine([1,2,3,5])
will give you
[
[
1
],
[
2
],
[
3
],
[
5
],
[
1,
2
],
[
1,
3
],
[
1,
5
],
[
2,
3
],
[
2,
5
],
[
3,
5
],
[
1,
2,
3
],
[
1,
2,
5
],
[
1,
3,
5
],
[
2,
3,
5
],
[
1,
2,
3,
5
]
]
and you can pass this arr to $in to find all the macthing elements
db.coll.find({a:{$in:arr}})
will give you
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
Wait!, its still not returning the remaining two possible items.
Because have a good look at the arr, it finds only the combination. it returns [1,3,5] but the data in document is [3,5,1]. So its clear that $in checks the items in given order (weird!).
So now you understand its the really hard comparing the mongodb query!. You can change the above JS combination former code to find the possible permutation to each combination and pass it to mongodb $in. Thats the trick.
Since you didn't mention any language choice its hard to recommend any permutation code. But you can find lot of different approaches in Stackoverflow or googling.
If I understood, you want to return only the objects whose all values of property a are in the find array argument.
By following the Travis' suggestion in the comments, you must follow these steps:
Define a JS function to achieve your desires (since there's no native way to do that in MongoDB);
Save the function on the server;
Use the function within $where.
If define your function to use only to that specific property (a, in this case), you may want skip the step 2. However, since it can be an useful function for other properties of other documents, I defined a more generic function, which must to be save on the server to be used AFAIK (I'm new on Mongo, too).
Below there are my tests on the mongo shell:
<--! language: lang-js -->
// step 1: defining the function for your specific search
only = function(property, values) {
for(var i in property) if (values.indexOf(property[i]) < 0) return false
return true
}
// step 2: saving it on the server
db.system.js.save( { _id : 'only', value : only } )
// step 3: using the function with $where
db.coll.find({$where: "only(this.a, [1,2,3,5])"})
With the 5 objects you provided on the question, you will obtain:
{ "_id" : ObjectId("4f3838f85594f902212eb532"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f3839075594f902212eb534"), "a" : [ 1, 2, 5 ] }
{ "_id" : ObjectId("4f38390e5594f902212eb535"), "a" : [ 3, 5, 1 ] }
The downside is performance. See more.