Printing a given tuple out of an array erlang - arrays

I am having some minor trouble with erlang, namely that I want to print out a given part of an array, however, I do not appear to be able to do so easily.
Here is the array I am trying to print using array:get(X, Array).
[{carrier, [{e,10}, {f,10}, {g,10}, {h,10}, {i,10}]},
{battleship, [{a,1}, {a,2}, {a,3}, {a,4}]},
{cruiser, [{e,3}, {e,4}, {e,5}]},
{destroyer, [{f,4},{g,4}, {h,4}]},
{patrol_boat, [{j,7},{j,8}]}]
I am able to print out the entire array however, I am unable to get just a single tuple out of it.
Ideally I would be able to do element(1, array:get(0, Array)). with the return of carrier.
Any help would be appreciated.

Your construct is a list, not an array. An Erlang array is something entirely different. You need to look at the lists module instead.
To get the first element, you can use pattern matching. Here's an example shell session:
1> List = [{carrier, [{e,10}, {f,10}, {g,10}, {h,10}, {i,10}]},
{battleship, [{a,1}, {a,2}, {a,3}, {a,4}]},
{cruiser, [{e,3}, {e,4}, {e,5}]},
{destroyer, [{f,4},{g,4}, {h,4}]},
{patrol_boat, [{j,7},{j,8}]}].
[{carrier,[{e,10},{f,10},{g,10},{h,10},{i,10}]},
{battleship,[{a,1},{a,2},{a,3},{a,4}]},
{cruiser,[{e,3},{e,4},{e,5}]},
{destroyer,[{f,4},{g,4},{h,4}]},
{patrol_boat,[{j,7},{j,8}]}]
2> [{ShipType, _}|_] = List.
[{carrier,[{e,10},{f,10},{g,10},{h,10},{i,10}]},
{battleship,[{a,1},{a,2},{a,3},{a,4}]},
{cruiser,[{e,3},{e,4},{e,5}]},
{destroyer,[{f,4},{g,4},{h,4}]},
{patrol_boat,[{j,7},{j,8}]}]
3> ShipType.
carrier
As you can see, ShipType will be set to carrier from this match.
To get other elements of the list, you can use lists:nth/2. For example, to get the entire 3rd element:
4> Third = lists:nth(3, List).
{cruiser,[{e,3},{e,4},{e,5}]}
For more info about Erlang lists, take a look at any Erlang book or any of these resources.

Related

Error when trying to set array in userdefaults: Thread 1: "Attempt to insert non-property list object

I have solved the issue now, thanks for your help. I shouldn't have tried to save arrays with UITextViews, but I should have saved their text as strings instead. Here was the original question:
I have tried a lot, and googled a lot, but I can't solve this problem on my own. Whenever I try to save an array in userdefaults, it just is not working. I get the following error:
Thread 1: "Attempt to insert non-property list object (\n "<UITextView: 0x14001f800; frame = (0 0; 355 180); text = 'D'; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600003f01d10>; layer = <CALayer: 0x6000031c83e0>; contentOffset: {0, 0}; contentSize: {355, 30}; adjustedContentInset: {0, 0, 0, 0}>"\n) for key content"
I don't know what a non-property list object is. And I do not know how to solve the problem. Below is the lines of code that do not work.
var contentList: [Any] = []
let cl = defaults.array(forKey: "content")!
if cl.count != 0{
contentList += cl
}
contentList.append(label)
defaults.setValue(contentList, forKey: "content")
If I take out the last line of code by turning it into a comment everything runs just fine. How should I replace that line of code? I essentially want to save an array of UITextViews and make it larger every time I call a fucntion (this code is part of a larger function). The reason why I have created another two lists (cl and contentList) is that it helps me with a problem down the line. What I cannot understand however, is why the last line of code doesn't work. If anyone has any ideas, please help me, it would be much appreciated.
Use only String as stated in comments :
var contentList: [String] = []
let cl = defaults.array(forKey: "content")!
if cl.count != 0{
contentList += cl
}
If lbText = label.text {
contentList.append(lbText)
defaults.setValue(contentList, forKey: "content")
}
You can only store a very limited list of data types into UserDefaults, commonly referred to as "property list objects" (Since property list (or plist) files will only store the same data types.
To quote the Xcode docs on UserDefaults, in the section titled "Storing Default Objects":
A default object must be a property list—that is, an instance of (or for collections, a combination of instances of) NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary [or Data, String, NSNumber, Date, Array, or Dictionary types in Swift.] If you want to store any other type of object, you should typically archive it to create an instance of Data.
(I added the equivalent Swift types to the above quote in square brackets, since it looks like Apple hasn't updated it for Swift.)
That's worded a little awkwardly. The idea is that you can only store data of the types listed. Because the Array and Dictionary types are "container" types, you can store any combination of arrays and dictionaries that contain combinations of any of the above types. For example, you can store an array that contains a dictionary, 3 dates, 2 floats, a Double, some Data, and 2 arrays, and those dictionaries and arrays can contain other dictionaries and/or arrays.)
It is almost always wrong to archive UIView objects like UITextViews. You should save the text properties of your text views instead.
If you want to manage a vertical stack of UITextView objects, I suggest adding a vertical stack view to your user interface, and then writing code that adds or removes UITextView subviews to your stack view. You should be able to find plenty of examples of adding and removing objects from stack views online. (It's really easy.)
If you want to manage a scrolling list of feeds of arbitrary length, you might want to use a table view or collection view instead. Those require that you set up a data model and implement a "data source". That takes a little practice to get right, but is very powerful.

Rails update remove number from an array attribute?

Is there a way to remove a number from an attibute array in an update? For example, if I want to update all of an alchy's booze stashes if he runs out of a particular type of booze:
Alchy has_many :stashes
Stash.available_booze_types = [] (filled with booze.ids)
Booze is also a class
#booze.id = 7
if #booze.is_all_gone
#alchy.stashes.update(available_booze_types: "remove #booze.id")
end
update: #booze.id may or may not be present in the available_booze_types array
... so if #booze.id was in any of the Alchy.stash instances (in the available_booze_types attribute array), it would be removed.
I think you can do what you want in the following way:
if #booze.is_all_gone
#alchy.stashes.each do |stash|
stash.available_booze_types.delete(#booze.id)
end
end
However, it looks to me like there are better ways to do what you are trying to do. Rails gives you something like that array by using relations. Also, the data in the array will be lost if you reset the app (if as I understand available_booze_types is an attribute which is not stored in a database). If your application is correctly set up (an stash has many boozes), an scope like the following in Stash class seems to me like the correct approach:
scope :available_boozes, -> { joins(:boozes).where("number > ?", 0) }
You can use it in the following way:
#alchy.stashes.available_boozes
which would only return the ones that are available.

Document each element of an array using spring-restdocs

I'm having a response which is an json array. Each element has it's meaning and I would be able to describe it.
My array:
["1525032694","300","true"]
I've found an example in the documentation that describes an array and each element which is the same:
https://docs.spring.io/spring-restdocs/docs/current/reference/html5/#documenting-your-api-request-response-payloads-fields-reusing-field-descriptors
But I would like to know how I can describe each of it as:
current timestamp, seconds to next measurement, should perform fota
My current test:
webTestClient.post().uri("/api//measurement/${SampleData.deviceId}")
.syncBody(SampleData.sampleMeasurement())
.exchange()
.expectStatus()
.isOk
.expectBody()
.consumeWith(document("add-measurement", responseFields(
fieldWithPath("[]")
.description("An array of device settings"))
))
Ok, it turns that be fairly easy:
responseFields(
fieldWithPath("[0]").description("Current timestamp"),
fieldWithPath("[1]").description("Device mode"),
fieldWithPath("[2]").description("Device parameter")
),

How to find which element failed comparison between arrays in Kotlin?

I'm writing automated tests for one site. There's a page with all items added to the cart. Maximum items is 58. Instead of verification of each element one by one I decided to create 2 arrays filled with strings: 1 with correct names : String and 1 with names : String I got from the site. Then I compare those 2 arrays with contentEquals.
If that comparison fails, how do I know which element exactly caused comparison fail?
Short simple of what I have now:
#Test
fun verifyNamesOfAddedItems () {
val getAllElementsNames = arrayOf(materials.text, element2.text,
element3.text...)
val correctElementsNames = arrayOf("name1", "name2", "name3"...)
val areArraysEqual = getAllElementsNames contentEquals correctElementsNames
if (!areArraysEqual) {
assert(false)
} else {
assert(true)
}
}
This test fails if 2 arrays are not the same but it doesn't show me the details, so is there a way to see more details of fail, e.g. element that failed comparison?
Thanks.
I recommend using a matcher library like Hamcrest or AssertJ in tests. They provide much better error messages for cases like this. In this case with Hamcrest it would be:
import org.hamcrest.Matchers.*
assertThat(getAllElementsNames, contains(*correctElementsNames))
// or just
assertThat(getAllElementsNames, contains("name1", "name2", "name3", ...))
There are also matcher libraries made specifically for Kotlin: https://github.com/kotlintest/kotlintest, https://yobriefca.se/expect.kt/, https://github.com/winterbe/expekt, https://github.com/MarkusAmshove/Kluent, probably more. Tests using them should be even more readable, but I haven't tried any of them. Look at their documentation and examples and pick the one you like.
You need to find the intersection between the two collections. Intersection will be the common elements. After than removing the intersection collection from the collection you want to perform the test will give you the complementary elements.
val intersection = getAllElementsNames.intersect(correctElementsNames)
getAllElementsNames.removeAll(intersection)

Select random item from an array with certain probabilities and add it to the stage

Its quite a big task but ill try to explain.
I have an array with a list of 200 strings and I want to be able to randomly select one and add it to the stage using code. I have movieclips exported for actionscript with the same class name as the strings in the array. Also, if it is possible, would I be able to select the strings with predictability such as the first has a 0.7 chance the second a 0.1 etc. Here is what i have currently
var nameList:Array=["Jimmy","Bob","Fred"]
var instance:DisplayObject = createRandom(nameList);
addChild(instance);
function createRandom(typeArray:Array):*
{
// Select random String from typeArray.
var selection:String = typeArray[ int(Math.random() * typeArray.length) ];
// Create instance of relevant class.
var Type:Class = getDefinitionByName(selection) as Class;
// Return created instance.
return new Type();
}
All this throws me this error
ReferenceError: Error #1065: Variable [class Jimmy] is not defined.
Ive searched for other threads similar but none combine the three specific tasks of randomisation, predictability and addChild().
I think that you've got two problems: a language problem and a logic problem. In the .fla connected to your code above, in the Library find each symbol representing a name and write into the 'AS linkage' column for that symbol the associated name -- e.g., 'Bob,' 'Fred' -- just the name, no punctuation.
Now getDefinitionByName() will find your 'Class'
If you put a different graphic into each MovieClip -- say, a piece of fruit or a picture of Bob,Jim, Fred -- and run your program you'll get a random something on stage each time.
That should solve your language problem. But the logic problem is a little harder, no?
That's why I pointed you to Mr. Kelly's solution (the first one, which for me is easier to grasp).

Resources