What is the correct use of the COMPARE statement in MS Word. I tried the following:
{SET FOO "foo" }
{COMPARE FOO "foo" }
{COMPARE { REF FOO } "foo" }
{COMPARE { FOO } "foo" }
{COMPARE FOO "Bar" }
{COMPARE { REF FOO } "Bar" }
{COMPARE { FOO } "Bar" }
If I switch off the field view (Alt-F9), I get:
0
0
0
0
0
0
I would expect that there is at least one "1". How can I achieve this?
{ COMPARE FOO = "foo" }
i.e. the basic syntax is
{ COMPARE comparand1 comparison-operator comparand2 }
But then you need to be a little bit careful. How things are compared depends on the type of comparand and the precise syntax. e.g.
{ SET foo "abc" }
{ COMPARE { foo } = "abc" } returns 1
{ SET foo "abc" }
{ SET abc "def" }
{ COMPARE { foo } = "abc" } returns 0
So { foo } is not treated quite the same as the bookmark "foo"
In this case you can avoid the problem by using the bookmark name alone, as before, i.e.
{ COMPARE foo = "abc" } returns 1
But if the comparand comes in from soemwhere else, e.g. you are comparing a { MERGEFIELD } field, then if the result of the MERGEFIELD is "foo" then this on its own
{ COMPARE { MERGEFIELD myfield } = "abc" } returns 0
but in this case
{ SET foo "abc" }
{ COMPARE { MERGEFIELD myfield } = "abc" } returns 1
In order to ensure that Word does not do an additional "dereference" you have to quote the comparand, i.e.
{ SET foo "abc" }
{ COMPARE "{ MERGEFIELD myfield }" = "abc" } returns 0
Word also converts/coerces texts that start with numbers into numbers in some circumstances, e.g.
{ SET foo "1abc" }
{ SET bar "1bcd" }
{ COMPARE foo = bar } returns 1
{ SET foo "1abc" }
{ SET bar "2bcd" }
{ COMPARE foo = bar } returns 0
So in that case, you would need
{ COMPARE "{ foo }" = "{ bar }" }
or
{ COMPARE "{ REF foo }" = "{ REF bar }" }
to get the comparison you probably expect.
Finally, the spaces around the comparison operator are significant. Even with no bookmark called xyz,
{ COMPARE xyz="abc" } returns 1
{ COMPARE xyz= "abc" } returns 1, but as you might hope
{ COMPARE xyz ="abc" } returns 0 and
{ COMPARE xyz = "abc" } returns 0
You need an operator (e.g. =) in the middle:
{ COMPARE FOO = "foo" }
Related
I'm working on search and want to get it error-proof.
let's say we have 3 strings: containsText that contains 2 words I'm looking for in fullTextShort and fullTextLong
My func contains works with fullTextShort as the words that I'm looking for are right after each other, but it doesn't work with fullTextLong where there's a world in between.
How to get the func to return true for both cases?
struct ContainsFuncView: View {
let fullTextShort = "I like pineapple"
let fullTextLong = "I like green pineapple"
let containsText = "like pineapple"
var body: some View {
VStack {
contains(type: "Short")
contains(type: "Long")
}
}
func contains(type: String) -> Text {
var containsInFullText: Bool = false
if type == "Short" {
containsInFullText = fullTextShort.localizedStandardContains(containsText)
}
else if type == "Long" {
containsInFullText = fullTextLong.localizedStandardContains(containsText)
}
return Text("\(containsInFullText ? "Contains" : "Doesn't contain") in fullText\(type)").foregroundColor(containsInFullText ? .green : .red)
}
}
Thank you!
Split containsText at the space. Then test if any or all words are in the text:
containsInFullText = containsText.components(separatedBy: " ").contains { fullTextShort.localizedStandardContains($0) }
containsInFullText = containsText.components(separatedBy: " ").allSatisfy { fullTextShort.localizedStandardContains($0) }
You can split the searched text into words and the reduce the search results for each word so the search returns true only when all words are found
let words = containsText.split(separator: " ")
if type == "Short" {
containsInFullText = words.reduce(true) { contains, word in
contains && fullTextShort.localizedStandardContains(word)
}
}
else if type == "Long" {
containsInFullText = words.reduce(true) { contains, word in
contains && fullTextLong.localizedStandardContains(word)
}
}
If you want to return true when at least one word is found, swap the && to || and the initial value to false
if type == "Short" {
containsInFullText = words.reduce(false) { contains, word in
contains || fullTextShort.localizedStandardContains(word)
}
}
else if type == "Long" {
containsInFullText = words.reduce(false) { contains, word in
contains || fullTextLong.localizedStandardContains(word)
}
}
Not sure if I'm asking this question properly or not. But basically I want to reference a member of a class by a string value and/or enum
For example I have the following.
var total:Int = 0
if locale.currencyCode == "JPY" {
for item in Cart.items {
total += item.fabric.price.JPY * item.quantity
}
}else{
for item in Cart.items {
total += item.fabric.price.USD * item.quantity
}
}
subtotalAmountLabel.text = "\(total.formatMoney())"
But, I'd like to write something like the following instead.
var total:Int = 0
for item in Cart.items {
total += item.fabric.price[locale.currencyCode]* item.quantity
}
subtotalAmountLabel.text = "\(total.formatMoney())"
Is there a possible way to do this?
You should use a dictionary instead.
// this should be the declaration of item.fabric.price
let prices = [
"JPY": <some price>,
"USD": <some price>,
// and so on
]
Then you can use a string to access it:
if let price = item.fabric.prices[locale.currencyCode] {
// ...
} else {
// If execution ever reaches here, that means there is no price available in that currency.
}
I am very new to Swift. I am trying to create func...
func circlesDisabledCondition(playerScoreValue: var) {
if playerScoreValue < 1 {
circle1.isEnabled = false
}
if playerScoreValue < 5 {
circle5.isEnabled = false
}
if playerScoreValue < 50 {
circle50.isEnabled = false
}
if playerScoreValue < 100 {
circle100.isEnabled = false
}
else {
circlesEnabled()
}
}
Of course (playerScoreValue: var) doesn't work, I have no idea how can I write it down.
Calling func example (wrong it is just example that I am looking for something like that...)
circlesDisabledCondition(playerScoreValue: player2ScoreValue)
I am looking for this output.
if player2ScoreValue < 1 {
circle1.isEnabled = false
}
if player2ScoreValue < 5 {
circle5.isEnabled = false
}
if player2ScoreValue < 50 {
circle50.isEnabled = false
}
if player2ScoreValue < 100 {
circle100.isEnabled = false
}
else {
circlesEnabled()
}
Many thanks
Replace var with whatever type your playerScoreValue is. If it's an integer, use Int, if it's a float, use float etc.
You can call your function with any variable or value as long as it's of the specified type.
Can I get a class by its name? For example:
class Foo {
}
class Bar {
}
let x = "Foo"
classByString(x) // need to return Foo
I want to use metaprogramming to reduce code maintenance.
You can use a NSClassFromString:
if let anyObj : AnyObject.Type = NSClassFromString("MyAppName.MySwiftClassFoo") {
//call Foo
} else {
//call Bar
}
Example:
#noreturn func setOnlyPropertyGetterError(__function__: String) {
fatalError("\(__function__) is set-only")
}
var property: Property {
get {setOnlyPropertyGetterError(__FUNCTION__)}
set {//useful work}
}
Can we avoid having to pass __FUNCTION__?
I think this is what you want to achieve:
#noreturn func writeOnlyProperty(propertyName: String = __FUNCTION__) {
fatalError("Property \(propertyName) is write-only")
}
class Foo {
var blackHole: Int {
get { writeOnlyProperty() }
set { print("Consuming value \(newValue)") }
}
}
let foo = Foo()
foo.blackHole = 1 // Prints "Consuming value 1"
let bar = foo.blackHole // Produces fatal error "Property blackHole is write-only"