I would like to store the values in array list after iterating the select options , is it possible in Watir - watir-webdriver

I am trying to store the values of select list in an array variable
a = b.options.each {|option| puts option.attribute_value "value" }
Output :
IN PROGRESS
UPCOMING
FINAL
POSTPONED
CANCELLED
a.to_i
Is it possible to store all values which getting from attribute and store in An array

The element collections in Watir include the Enumerable module, which gives a lot of useful methods for iterating. In particular, it includes a map method that will perform a block on each element and collect the result in an array.
To store the value of all options, you can simply do:
total_list_values = #browser.options.map(&:value)
#=> ["IN PROGRESS", "UPCOMING", "FINAL", "POSTPONED", "CANCELLED"]

I coded it like this and its worked, posted if anyone wanted this
total_list_values = Array.new
body = #browser.options
body.options.each do |option|
total_list_values << option.value
end

Related

Apply filtering with an array of value instead of one value for a filter in Algolia

I have in my index a list of object, each of them has an objectID value.
On some search, i want to filter OUT a certain number of them, using there objectID.
For the moment it works with one value as a string, i would like to know how to do for multiple value.
filters = 'NOT objectID:' + objectIDToFilter;
This work for one object, what can i do to apply this for an array of ObjectID. because :
filters = 'NOT objectID:' + arrayObjectID;
does not work.
I was thinking of generating a huge string with an arrayId.map with all my 'NOT objectID:1 AND NOT objectID: 2 ...' but i wanted to know if there is a cleaner way to do it.
I unfortunately misunderstood the line in algolia doc :
Array Attributes: Any attribute set up as an array will match the filter as soon as one of the values in the array match.
This apparently refers to the value itself in Algolia and not the filter
So i did not found a solution on algolia doc, i went for the long string, hope there is no limits on how much filter we can add on a query (found nothing about that).
Here is what i did if someone need it :
let filters = `NOT objectID:${userID}`;
blockedByUsers.map((blockedByUser) => {
filters = filters + ` AND NOT objectID:${blockedByUser}`;
});
If you need to add multiple but don't have a starting point like i do, you can't start the query with an AND , a solution i found to bypass that:
let filters = `NOT objectID:${blockedByUsers[0]}`;
blockedByUsers.map((blockedByUser, i) => {
if (i > 0) filters = filters + ` AND NOT objectID:${blockedByUser}`;
});
There is probably a cleaner solution, but this work. If you have found other solution for that problems i'll be happy to see :)

Equivalent of StructKeyList() for struct value

StructKeyList() will give me list of struct key with comma delimited. Now I need to get struct value with comma delimited. Right now this is what I'm doing to get value
<cfloop collection="#form#" item="key" >
#form[key]#,
</cfloop>
How can I get list of value from struct without loop? Thanks in advance.
I go through your problem. As per my knowledge is not possible to get list of value in structure within single functions. We have to loop the key and get the value of each. But I can give a solution for to get struct value with comma delimited.
<cfset strNew = {"a":"10","b":20,"c":30}>
Here strNew is my sample structure.
<cfset myList = ''>
<cfloop collection="#strNew#" item="key" >
<cfset myList = listappend(myList,structfind(strNew,key))>
</cfloop>
<cfdump var="#myList#" />
Here I've loop over the structure keys and find the value of an particular key and append that in to and list by using listappend and structfind functions.
So you no need to put like #structure[key]#,In your end of comma(,) is also added the last value of key too. For example your code should return 10,20,30,.
So you no need to do like that. use structfind and listappend you can avoid end of the comma also. Hope it's help you.
Since you're using CF2016, if you want to avoid a loop, you can always use one of the higher-order functions like reduce().
fields = formScope.reduce( function(result, key, value) {
result.append(value) ;
return result ;
}, [] ) ;
This takes the struct of your form scope (formscope) and uses reduce() to step through it and take it down to a single value (which is the struct values turned into an array). Then we make the returned array into a list.
writeDump( fields.toList() )
My full test code is at https://trycf.com/gist/f00cc62cd4631f44070faf8008e6788f/acf2016?theme=monokai
<cfscript>
formScope = {
empty1 : "" ,
fieldl : "text1" ,
field2 : "text2" ,
empty2 : "" ,
field3 : "text3" ,
field4 : "text4" ,
empty3 : ""
} ;
fields = formScope?.reduce( function(result, key, value) {
len(value) ? result.append(value) : "" ;
return result ;
}, [] ) ;
writeDump( fields?.toList() ?: "Form doesn't exist." ) ;
</cfscript>
Giving us: text2,text3,text4,text1.
formScope is my simulated version of the form fields that would be passed to this page. I use mostly the member function versions of StructReduce, ArrayAppend and ArrayToList. I also use the initialVal optional parameter to initialize the reduction's result value as an array. I check that the value has a length (I could also trim if needed) before I insert a row in the array, allowing me to remove empty elements from my final list. I also use the safe navigation operator (?.) to do some basic validation to make sure the elements exist (like if the form didn't pass or the reduction produced invalid results) and to make it more error-resistant.
NOTE: I believe that can be taken back to be compatible with CF11, when ArrayReduce was introduced.
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-s/structreduce.html
http://ryanguill.com/functional/higher-order-functions/2016/05/18/higher-order-functions.html
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arraytolist.html

How to get certains values from Eloquent collection?

I have an Eloquent collection (already executed query) and I need to do some things with two items from this array so I need to use only or pluck methods but they dont return what I need...
$orders = Order::with('parts')->paginate(50);
$orders[0]->parts->lists('name'); // Returns names
$orders[0]->parts->lists('custom_name'); // Returns custom names
$orders[0]->parts->only(['name', 'custom_name']); // Returns nothing
$orders[0]->parts->pluck(['name', 'custom_name']); // Returns no values
The only method returns the items in the collection with the specified keys. Since Colllection keys are not those column names you specified but simple incrementing numbers you won't get result by using only method.
The pluck method retrieves all of the collection values for a given key.
so You must use
$orders[0]->parts->pluck('name', 'custom_name');
insted of
$orders[0]->parts->pluck(['name', 'custom_name']);
remove those [ ] and it should work fine.

MongoDB: Performing actions on a field of a collection

I am very new to MongoDB (only got started out of interest last week). I am trying to figure out something and I'm not entirely sure of the terminology to go about searching for it. So I decided to make a SO question.
I created a collection called Students. Students has the fields id, name, undergrad(which is a boolean), classes(which is an array) and units(which is 3 times the number of classes the student has).
Now, I wanted to see how I could perform actions on a particular field of Students. What I did was, inserted a couple documents and purposefully did not include the units field. And I wanted to $set the units field forEach document/student that did not have the field. I did the following:
var studentDoc = db.students.find({units: {$exists:false}})
studentDoc.forEach(function(stu){
db.student.update({_id:stu._id}, {$set:{units:{$size:"$classes"}}})
}
)
Question 1: Is what I've done even remotely correct?
Question 2: When I type studentDoc after setting the var studentDoc, it doesn't print anything. But when I write
var studentDoc = db.students.find({units:{$exists:false}}).toArray()
it prints studentDoc as an array but still doesn't seem to do anything in the forEach loop.
Question 3: How do I $set the units field as 3 * (size of classes array)
I hope I have been clear in my question. I have tried searching on the MongoDB docs and google, but haven't had any luck (probably because of my lack of knowledge to search for the correct things).
Any help would be great! You can even point me in the right direction, and that'll be great!
Thank you in advance for all your help!!
I'm not sure why foreach not getting in. You can do the same with below working code.
for(i=0;i<studentDoc.length();i++){
var stud_id = studentDoc[i]._id;
var doc = db.students.findOne({"_id":stud_id})["classes"];
if(doc){
var len = doc.length;
db.students.update({"_id":stud_id},{$set:{"units":len*3}})
}
}
As far as I know, You can't use $size:"$" queries in update statement. you will get error like below:
The dollar ($) prefixed field '$size' in 'units.$size' is not valid for storage.
The return value of db.collection.find() is cursor.
In the mongo shell, if the returned cursor is not assigned to a variable using the var keyword, the cursor is automatically iterated up to 20 times to access up to the first 20 documents that match the query. To iterate manually, assign the returned cursor to a variable using the var keyword. So
var studentDoc = db.students.find({units: {$exists:false}})
You should iterator studentDoc manually.
Whereas, the cursor.toArray() returns an array that contains all the documents from a cursor. The method iterates completely the cursor, loading all the documents into RAM and exhausting the cursor. Thus
var studentDoc = db.students.find({units:{$exists:false}}).toArray()
it prints studentDoc as an array.
If you want to use forEach, here is cursor.forEach().
db.students.find({units:{$exists:false}}).forEach()
var studentDoc = db.students.find({units: {$exists:false}})
here studentDoc is a cursor, it's not printable.
you can use forEach
studentDoc.forEach(printjson);
or iterator the cursor
while (studentDoc.hasNext()) {
printjson(studentDoc.next());
}

Composite views in couchbase

I'm new to Couchbase and am struggling to get a composite index to do what I want it to. The use-case is this:
I have a set of "Enumerations" being stored as documents
Each has a "last_updated" field which -- as you may have guessed -- stores the last time that the field was updated
I want to be able to show only those enumerations which have been updated since some given date but still sort the list by the name of the enumeration
I've created a Couchbase View like this:
function (doc, meta) {
var time_array;
if (doc.doc_type === "enum") {
if (doc.last_updated) {
time_array = doc.last_updated.split(/[- :]/);
} else {
time_array = [0,0,0,0,0,0];
}
for(var i=0; i<time_array.length; i++) { time_array[i] = parseInt(time_array[i], 10); }
time_array.unshift(meta.id);
emit(time_array, null);
}
}
I have one record that doesn't have the last_updated field set and therefore has it's time fields are all set to zero. I thought as a first test I could filter out that result and I put in the following:
startkey = ["a",2012,0,0,0,0,0]
endkey = ["Z",2014,0,0,0,0,0]
While the list is sorted by the 'id' it isn't filtering anything! Can anyone tell me what I'm doing wrong? Is there a better composite view to achieve these results?
In couchbase when you query view by startkey - endkey you're unable to filter results by 2 or more properties. Couchbase has only one index, so it will filter your results only by first param. So your query will be identical to query with:
startkey = ["a"]
endkey = ["Z"]
Here is a link to complete answer by Filipe Manana why it can't be filtered by those dates.
Here is a quote from it:
For composite keys (arrays), elements are compared from left to right and comparison finishes as soon as a element is different from the corresponding element in the other key (same as what happens when comparing strings à la memcmp() or strcmp()).
So if you want to have a view that filters by date, date array should go first in composite key.