Accessing to 2D array with a range in Swift - swift

When I construct 2D array as follows, and apply flatMap with a range on it, I get the following result:
var a = [["5", "3", ".", ".", "7", "."],["6",".",".","1","9","5"]]
print(a.flatMap{$0[1..<5]})
output:
["3", ".", ".", "7", ".", ".", "1", "9"]
But if I want to just display the range as follows, I am getting the following error.
print(a[1..<5])
Terminated by signal 4

The crash is exactly what one would expect. a has just two elements, indexed as 0 and 1. Applying a larger index by saying a[1..<5] (asking also for elements 2, 3, and 4) puts you out of range.

If you think of the elements in the range as columns of the 2D Array, then you could get them this way:
let a = [["5", "3", ".", ".", "7", "."],
["6", ".", ".", "1", "9", "5"]]
func getColumns<T>(in range: Range<Int>, from array2d: [[T]]) -> [T] {
return array2d.flatMap { $0[range] }
}
getColumns(in: 1..<5, from: a) //["3", ".", ".", "7", ".", ".", "1", "9"]
Bear in mind that this could still throw an Index out of range error just like with any other array.

Related

Dart : Compare between different type of list

I have two type of list.
Here,
List list1= [
{"id": "3", "topic_name": "Studying In Bangladesh"},
{"id": "4", "topic_name": "Studying In Sweden"},
{"id": "6", "topic_name": "Studying In Germany"},
];
List list2 = [
"2",
"3",
"5",
"6",
];
I want to generate a new topic list from list1, which is matched by list2's elements ( with list1's id ).
Is there any method are available for dart ?
You can do this:
List list3 = list1.where((e) => list2.contains(e['id'])).toList();
You can compare list1's id element with the list 2 with the foreach property in list for iterate through all elements of the list

Create Array of Dates from JSON

I would like to create an array of dates (or of tuples including an index and a data) from the following JSON.
My code is creating an array but instead of creating an array of dates, it breaks up the dates into characters. What do I need to do to create an array just of dates.
JSON looks like:
let json = """
[{"date":"2017-01-05",
"price":119.34},{"date":"2017-01-06",
"price":118.93}];
Code is:
let myprices = try JSONDecoder().decode([Prices].self, from: Data(json.utf8))
let dates = myprices.sorted{$0.date < $1.date}.enumerated().map {Array($0.element.date)}
Code prints to console as:
dates [["2", "0", "1", "7", "-", "0", "1", "-", "0", "5"], ["2", "0", "1", "7", "-", "0", "1", "-", "0", "6"], ["2", "0", "1", "7", "-", "0", "1", "-", "0"]]
Thanks in advance for any suggestions.
Replace
let dates = myprices.sorted{$0.date < $1.date}.enumerated().map {Array($0.element.date)}
with
let dates = myprices.sorted{$0.date < $1.date}.map { $0.date }
Currently you may be making let data:String change it to let date:Date and supply a formatter to the decoder check This

Inserting into selected item of sub array in mongodb

My data is as follows:
{
"_id": {
"$oid": "5e57db66c6bb04eb902589a2"
},
"name": "temp1",
"sub_arr": [{
"_id_": "53",
"_text": "Different ministries & states are working together",
"labels": ["A", "B", "C", "D", "E"]
}, {
"_text": "We need to work together, take small yet important measures to ensure self-protection.",
"_id_": "54",
"labels": ["A", "B", "C", "D", "E", "F"]
}]
}
I can get the item of the subarray that I need as follows:
db.mycollection.find({"name":"temp1"}, {"sub_arr":{"$elemMatch": {"_id_": "54"}}})
Now I would like to insert into that item another sub array as follows:
db.mycollection.find({"name":"temp1"}, {"sub_arr":{"$elemMatch": {"_id_": "54"}}}).upsert.updateOne({'ins_labels': [{"id": "a1", "label": "A"}]})
However it does not work. Please help
db.mycollection.update({"name":"temp1","sub_arr._id_":"54"},{"$set":{"sub_arr.$.ins_labels":[{"id": "a1", "label": "A"}]}})
mongo maintains the position of the array list when array is part of the query.

Compiling failed: argument type 'Character' does not conform to expected type 'ExpressibleByStringLiteral'

I have this code:
private func validate(text: String) -> String {
let acceptableChar: Set<Character> = ["0", "9", "8", "7", "6", "5", "4", "3", "2", "1", "."]
// let acceptableChar: [Character] = ["0", "9", "8", "7", "6", "5", "4", "3", "2", "1", "."]
var clearText = text
clearText.removeAll(where: { !acceptableChar.contains($0) })
return clearText
}
that work fine in Xcode Version 11.3.1 (11C504) in every device (iPhone, iPad and Mac), but in PreviewProvider, I have this error:
Compiling failed: argument type 'Character' does not conform to expected type 'ExpressibleByStringLiteral'
.....
error: argument type 'Character' does not conform to expected type 'ExpressibleByStringLiteral'
let acceptableChar: Set<Character> = [__designTimeString("#2775.[2].[0].value.[0].[0].value", fallback: "0"), __designTimeString("#2775.[2].[0].value.[1].[0].value", fallback: "9"), __designTimeString("#2775.[2].[0].value.[2].[0].value", fallback: "8"), __designTimeString("#2775.[2].[0].value.[3].[0].value", fallback: "7"), __designTimeString("#2775.[2].[0].value.[4].[0].value", fallback: "6"), __designTimeString("#2775.[2].[0].value.[5].[0].value", fallback: "5"), __designTimeString("#2775.[2].[0].value.[6].[0].value", fallback: "4"), __designTimeString("#2775.[2].[0].value.[7].[0].value", fallback: "3"), __designTimeString("#2775.[2].[0].value.[8].[0].value", fallback: "2"), __designTimeString("#2775.[2].[0].value.[9].[0].value", fallback: "1"), __designTimeString("#2775.[2].[0].value.[10].[0].value", fallback: ".")]
Anyone know how to modify the private func validate(text: String) -> String { to eliminate this error?
Use the following declaration
let acceptableChar = Set<Character>(arrayLiteral:
"0", "9", "8", "7", "6", "5", "4", "3", "2", "1", ".")
Tested & worked with Xcode 11.2 / iOS 13.2
I did a small hack that made it work in Xcode Previews
extension Character: ExpressibleByStringLiteral {
public init(stringLiteral value: StringLiteralType) {
self.init(value)
}
}
Use a CharacterSet
import Foundation
func filter(_ input: String) -> String {
var allowed = CharacterSet.decimalDigits
allowed.insert(".")
return String(input.unicodeScalars.filter { allowed.contains($0) })
}
print(filter("a123123b123152345.1j123412340"))
If you are using SwiftUI this is an simple solution:
yourString.split(separator: Character(" "))
Tested and worked with Xcode 11.5

expected conditions with JSON objects

I am making an API call which returns a JSON Structure in the response:
{
"tags": [],
"scope": "all",
"tenant_id": "0",
"version": 1,
"type": "tenant",
"description": "",
"name": "3",
"body":{
"settings": {},
"tenant_id": "2",
}
}
When I am trying to compare
expect(res.body.name).toBe(3);
or
expect(res.body.name).toEqual(3);
It fails and gives follwoing error:
Expected '3' to be 3.
or
Expected '3' to Equal 3.
Your are equating string '3' to number 3, that is the reason for the failure. You can use the following code:
expect(res.body.name).toEqual("3");
OR
expect(res.body.name).toBe("3");
"name": "3", makes it sound as though expect(res.body.name).toEqual('3'); should work since "3" is a string.
Also in that same vein:
expect(res.body.name).toBe('3'); in case your code style prefers === checks over ==
expect(Number(res.body.name)).toEqual(3); in case you need to be expecting the number 3 regardless of the exact type of 3.
If the api response was "name": 3,, your tests would be good as is, but it seems as though the implementation has it stored as a string. Either file a bug if it needs to be a number, have your expectations be strings as well, or convert the api response to a number before asserting.
I don't think you need to expect literally '3', just 3 the string rather than 3 the number.