How to get all elements even if they have the same data - javascript

I have a project where I would like to gather in all brandname and price from a site.
for that reason I have the following code:
List<WebElement> list_of_products = driver.findElements(By.xpath(loc.getProperty("brandName")));
List<WebElement> list_of_products_price = driver.findElements(By.xpath(loc.getProperty("finalPrice")));
//System.out.println("ezek a termékek"+ list_of_products);
// Use of HashMaop to store Products and Their prices(after conversion to
// Integer)
String product_name;
String product_price;
int int_product_price;
HashMap<Integer, String> map_final_products = new HashMap<>();
{
for (int i = 0; i < list_of_products.size(); i++) {
product_name = list_of_products.get(i).getText();// Iterate and fetch product name
product_price = list_of_products_price.get(i).getText();// Iterate and fetch product price
product_price = product_price.replaceAll("[^0-9]", "");// Replace anything will space other than numbers
int_product_price = Integer.parseInt(product_price);// Convert to Integer
map_final_products.put(int_product_price, product_name);// Add product and price in HashMap
}
// write out all the products we found
Reporter.log("All the prices and products we found: " +
map_final_products.toString()+ "\n", true);
// Get all the keys from Hash Map
Set<Integer> allkeys = map_final_products.keySet();
ArrayList<Integer> array_list_values_product_prices = new ArrayList<Integer>(allkeys);
// this will sort in ascending order lowest at the top and highest at the bottom
Collections.sort(array_list_values_product_prices);
As it is on console:
XYs are the actual brandnames
All the prices and products we found: {20720=XY,
11490=XY, 13490=XY, 15490=XY,
19490=XY, 21990=XY, 16490=XY, 18490=XY
20490=XY, 18990=XY, 20990=XY}
As I think my code just does not write out or collect when the price is the same with other brands(or with the same brands too). For example:
At the website there are more products for 13490.. and lots of for 18490.
How can I modify my code in order to get all the pairs even if they have same prices?

#Peter Santa, you should have product Name as your key instead of Price. So you can reverse the location. But this will not print the same product with the same or different price. Which I feel should be ok assuming, the same product will not have different prices on the same website.

Related

looping over objects javascript

So recently I learned about using for in loops to loop over objects. We were given this problem to solve regarding a basic cart object that contains name of object and then quantity and price.
const cart = {
"Gold Round Sunglasses": { quantity: 1, priceInCents: 1000 },
"Pink Bucket Hat": { quantity: 2, priceInCents: 1260 },
};
We have to write 2 functions, one that calculates total cost of inventory in cents and the other displays the inventory.
The calculateCartTotal function will take in the cart and return a total price, in cents, of everything inside of it.
The printCartInventory function will take in the cart and return a string, joined by \n, of the quantity and name of each item.
I was able to the finish question one with ease but am struggling with the 2nd one.
1st function:
function calculateCartTotal(cart) {
let total = 0;
for(let item in cart){
const product = cart[item]
const quantity = product.quantity
const price = product.priceInCents
total += quantity * price
}
return total
}
2nd function:
function printCartInventory(cart) {
let inventory = ""
for(let item in cart){
const product = cart[item]
const quantity = product.quantity
inventory += `${quantity}x${product}/n`
}
return inventory
}
When I test the 2nd function the autograder gives this error:
expected '2x[object Object]/n1x[object Object]/n1x[object Object]/n3x[object Object]/n' to include '2xCanvas Tote Bag\n1xBlack and White Chuck On Dress\n1xNatural Straw Wide Brim Hat\n3xBlue Stripe Casual Shirt'
When you look at the error message, note the part that says [object Object]. This is part of your code's output, and should ring a bell. It means your code tries to put an object in a string, instead of a string.
The guilty code is here:
inventory += `${quantity}x${product}/n`
product is not a string, but an object. It is not what you intended to output there. What you want to output is the name of the product, which is the key, not the value associated with that key. So it should be:
inventory += `${quantity}x${item}/n`

Discord.js get rank position of user

I want to get the number of users that have a lower number of XP points than the member who used the command, this way I can get his rank.
However I don't know much in javascript and sql queries, and I'm hard stuck with this, where it simply returns [object Object] instead of a number.
My sql table
const table = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';").get();
if (!table['count(*)']) {
// If the table isn't there, create it and setup the database correctly.
sql.prepare("CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER, level INTEGER, money INTEGER);").run();
// Ensure that the "id" row is always unique and indexed.
sql.prepare("CREATE UNIQUE INDEX idx_scores_id ON scores (id);").run();
sql.pragma("synchronous = 1");
sql.pragma("journal_mode = wal");
}
// And then we have two prepared statements to get and set the score data.
client.getScore = sql.prepare("SELECT * FROM scores WHERE user = ? AND guild = ?");
client.setScore = sql.prepare("INSERT OR REPLACE INTO scores (id, user, guild, points, level, money) VALUES (#id, #user, #guild, #points, #level, #money);");
});
My attempt
if (message.content.startsWith(prefix + "cl stats")) {
const curxp = score.points;
client.rank = sql.prepare("SELECT count(*) FROM scores WHERE points >= #curxp AND guild = #guild").get();
console.log(client.rank);
await message.reply(`${client.rank}`);
}
Found a solution. Probably not the best but it works.
client.getRank = sql.prepare("SELECT count(*) FROM scores WHERE points >= ? AND guild = ?");
function getRank(){
const curXP = score.points;
let rankOBJ = client.getRank.get(curXP, message.guild.id)
console.log(rankOBJ);
let rankStr = JSON.stringify(rankOBJ);
let rank = rankStr.match(/\d/g);
return rank;
};

Loop and concatenate same VAR

Is it possible to use do{}while() to concatenate the same var depending on the result of another var?
I am running a loop where I capture Customers and their Payments, each line is a result, sometimes for the same customer I have 2 or more Payments, i.e:
Customer A --- 'Payment#01' --- $10.00
Customer A --- 'Payment#02' --- $10.00
Customer B --- 'Payment#01' --- $10.00
Customer B --- 'Payment#02' --- $10.00
Customer B --- 'Payment#03' --- $10.00
[...]
I want to check the customer on the first line and while the next line continues with the same customer I'd like to concatenate each result in one string, so I will have something like this:
Customer A --- 'Payment#01,Payment#02' --- $20.00
Customer B --- 'Payment#01,Payment#02,Payment#03' --- $30.00
[Edit: code so far]
try{
do{
resultSet = searchResults.getResults(resultIndex, resultIndex + resultStep);
resultIndex = resultIndex + resultStep;
for(var i = 0; !!resultSet && i < resultSet.length; i++){
var results = resultSet[i];
var columns = results.getAllColumns();
var customer = results.getValue(columns[0]);
var paymentamt = results.getValue(columns[1]);
var document = results.getValue(columns[2]);
}
} while (!!resultSet && resultSet.length > 0)
} catch(error){
var message = error.message;
}
If the customers are always in a neat order, ie you won't ever get Customer A, Customer B, Customer A, then just use a variable to keep track of the current customer ID, current payment string, and current value.
Loop through the lot - is the customer ID at [loop] the same as the current one? If yes, add to the string and value.
If not, output (or whatever you do with it) the current line, reset all the variables to this new customer's data.
If they can arrive out of order then you could store the values in an object - eg. customerRecord = {customerID : { paymentstring:, value:}}.
As you read in the next customer in the loop, check if it exists in the object (hasOwnProperty if you use the customerID as a key as above) and add to its values. If not, add a new object to customerRecord.
The most generic approach is to keep an object with keys or the more modern Map to keep the totals and all payments. The most direct approach would be to keep objects and simply keep appending the string. An alternative is to keep the separate payments (descriptions) inside those objects and only concatenate them when displaying. For example:
//this part is just for emulating the resultset
let resultSet =[ {vals:['Customer A' ,'Payment#01' ,10.00]}, {vals:['Customer A' ,'Payment#02' ,10.00]}, {vals:['Customer B' ,'Payment#01' ,10.00]}, {vals:['Customer B' ,'Payment#02' ,10.00]}, {vals:['Customer B' ,'Payment#03' ,10.00]} ];resultSet.forEach(o=> {o.getAllColumns = ()=> [0,1,2]; o.getValue = i => o.vals[i]});
let map = new Map(); // <- declare outside the do..while , if it should concatenate customers from all searches, otherwise inside
do{
//get result set code...
if(!resultSet)break;
for(var i = 0; i < resultSet.length; i++){
let results = resultSet[i],
columns = results.getAllColumns();
customer = results.getValue(columns[0]),
tot = map.get(customer);
if(!tot) map.set(customer,tot = {customer:customer, payments:[], totalAmt:0, get Payments(){return this.payments.join(', ');} , toString: function(){return `${this.customer} --- ${this.Payments} --- ${this.totalAmt}`;}});
tot.payments.push(results.getValue(columns[1]));
tot.totalAmt += results.getValue(columns[2]);
}
}while(false); //replace with your own while (since break is used, you could simply do while(true))
//test output code.
for(let tot of map.values())
console.log(tot.toString());

Search array of string keys for matching variable and return all values using javascript / jquery

I am building an ecommerce application, part of which creates a cookie when the user adds products to a basket (US English: please read 'cart'). The application's logic often generates multiple baskets (and therefore multiple cookies) per user. Each cookie is given a key, which always begins with the string 'basket' following by an ascending integer. Each basket is given an id, which is a 32 character string, stored as the cookie's value.
Within the cookies, the user's basket ids are stored as strings, each with a name / value pair. I have managed to push all of the cookie name / value pairs into an array, such that the array reads:
["mcart=537244a1377f97374fff2233cdc29bdf", " mtoken=0f9a74b73d2f29b1c6088d63b7f4f4a5c545bbe9", " mexpires=1468626166000", " basket1=aw7j0r9ke3hq8tp20egf7105dozfn13i", " basket2=kpxpdnw6nnfyvawmk7n4s7pd9meaimy7", " basket3=9264k594wi9vgfiotkvz323n35yfvkkf"]
I have created a variable:
var name = 'basket';
My aim is to use javascript (presumably regex), or indeed jquery, to:
return the values for the key/value pairs with keys matching 'basket1', 'basket2' and 'basket3' (please note the extra space in the keys which directly follows the opening quotation marks);
continue to match and return values for future key/value pairs created (e.g. 'basket4', 'basket5', 'basket91');
return said values in an javascript array.
THANK YOU in advance to the community.
var cookies = ["mcart=537244a1377f97374fff2233cdc29bdf", " mtoken=0f9a74b73d2f29b1c6088d63b7f4f4a5c545bbe9", " mexpires=1468626166000", " basket1=aw7j0r9ke3hq8tp20egf7105dozfn13i", " basket2=kpxpdnw6nnfyvawmk7n4s7pd9meaimy7", " basket3=9264k594wi9vgfiotkvz323n35yfvkkf"];
var baskets = [];
for (var i = 0; i < cookies.length; i++) {
var match = cookies[i].match(/basket\d+=(.*)/);
if (match) {
baskets.push(match[1]);
}
}
console.log(baskets);
// Output:
// [ 'aw7j0r9ke3hq8tp20egf7105dozfn13i',
// 'kpxpdnw6nnfyvawmk7n4s7pd9meaimy7',
// '9264k594wi9vgfiotkvz323n35yfvkkf' ]

Find separation values from a starting node

I found on some online coding exercises and this one looks really cool and I wanted to give it a shot.
Problem Statement
Quinn is a pretty popular, and extremely modest guy. Other students measure their popularity in a unit called QDist.
One can calculate their QDist value by finding the degrees of separation between their self and Quinn. For example:
If Quinn is friends with Dave, and Dave is friends with Travis, then Dave's QDist value is 1, and Travis is 2.
Output
name QDist for each person entered ordered alphabetically by name.
In the event that a person is not connected to Quinn in anyway, output name uncool
Given a list of friendships, list each person and their QDist value in alphabetical order.
Sample Input/output
10
Alden Toshiko
Che Kortney
Che Dorian
Ronda Lindell
Sharon Alden
Dorian Quinn
Owen Sydnee
Alden Che
Dorian Tyra
Quinn Ally
Output
Alden 3
Che 2
Dorian 1
Kortney 3
Lindell uncool
Ally 1
Owen uncool
Quinn 0
Ronda uncool
Sharon 4
Sydnee uncool
Toshiko 4
Tyra 2
My Approach
Firstly, I don't want the answer I just want a hint or some guidance on how I should approach the problem in javascript (as its the language i'm the most familiar with). My thought was to break the program into an object and arrays, and try to create a family relationship between each name, sort of as a nested object or perhaps an array. Then I could use some sort of recursion to find how deep the array or object goes.
What would be the best approach?
From the input you could create a list of persons. It could be an object, where each key is a person's name, and the corresponding value is an array of names, representing the friends of that person. Of course you should make sure that when you add B as a friend of A, you must also add A as a friend of B.
For the example input, the above structure would look like this:
{
"Alden": ["Toshiko","Sharon","Che"],
"Toshiko": ["Alden"],
"Che": ["Kortney","Dorian","Alden"],
"Kortney": ["Che"],
"Dorian": ["Che","Quinn","Tyra"],
"Ronda": ["Lindell"],
"Lindell": ["Ronda"],
"Sharon": ["Alden"],
"Quinn": ["Dorian","Ally"],
"Owen": ["Sydnee"],
"Sydnee": ["Owen"],
"Tyra": ["Dorian"],
"Ally": ["Quinn"]
}
Then keep track of a list of names, starting with just Quinn, and also a distance, starting at 0.
Then for each name in that list, assign the current distance as their QDist value. Then find their friends and put them all together. Remove names that have already received a QDist value.
Then increase the distance, and repeat the above for that new list of names.
Keep repeating until the list of names is empty.
Note that if you do things in the right order, you can replace a persons list of friends by the QDist value. So the above structure would change after the first two iterations to:
{
"Alden": ["Toshiko","Sharon","Che"],
"Toshiko": ["Alden"],
"Che": ["Kortney","Dorian","Alden"],
"Kortney": ["Che"],
"Dorian": 1,
"Ronda": ["Lindell"],
"Lindell": ["Ronda"],
"Sharon": ["Alden"],
"Quinn": 0,
"Owen": ["Sydnee"],
"Sydnee": ["Owen"],
"Tyra": ["Dorian"],
"Ally": 1
}
When the algorithm finishes, you have:
{
"Alden": 3,
"Toshiko": 4,
"Che": 2,
"Kortney": 3,
"Dorian": 1,
"Ronda": ["Lindell"],
"Lindell": ["Ronda"],
"Sharon": 4,
"Quinn": 0,
"Owen": ["Sydnee"],
"Sydnee": ["Owen"],
"Tyra": 2,
"Ally": 1
}
Now the remaining friends arrays need to be replaced with "uncool", as apparently the corresponding people have no connection with Quinn. Also the list needs to be sorted.
Spoiler warning!
Here is a working snippet:
// Get input as text
var input = `10
Alden Toshiko
Che Kortney
Che Dorian
Ronda Lindell
Sharon Alden
Dorian Quinn
Owen Sydnee
Alden Che
Dorian Tyra
Quinn Ally`;
// Build persons list with friends list
var persons =
// Take the input string
input
// Split it by any white-space to get array of words
.split(/\s+/)
// Skip the word at position 0: we don't need the line count
.slice(1)
// Loop over that array and build an object from it
.reduce(
// Arguments: obj = result from previous iteration
// name = current name in names array
// i = index in that array
// names = the whole array being looped over
(obj, name, i, names) => (
// Get the list of friends we already collected for this name.
// Create it as an empty array if not yet present.
obj[name] = (obj[name] || [])
// Add to that list the previous/next name, depending
// whether we are at an odd or even position in the names array
.concat([names[i%2 ? i-1 : i+1]])
// Use the updated object as return value for this iteration
, obj)
// Start the above loop with an empty object
, {});
// Now we have a nice object structure:
// { [name1]: [friendName1,friendName2,...], [name2]: ... }
// Start with Quinn as the only person we currently look at.
var friends = ['Quinn'];
// Increment the distance for each "generation" of friends
// until there are none left.
for (var i = 0; friends.length; i++) {
// Replace the friends list with a new list,
// while giving the friends in the current list a distance
friends =
// Start with the current list of friends
friends
// Loop over these friends.
// Only keep those that still have a friends array (object) assigned to them,
// since the others were already assigned a distance number.
.filter(friend => typeof persons[friend] === "object")
// Loop over those friends again, building a new list of friends
.reduce((friends, friend, k) => [
// Add this friends' friends to the new list
friends.concat(persons[friend]),
// ... and then replace this friends' friend list
// by the current distance we are at.
persons[friend] = i
// Return the first of the above two results (the new list)
// for the next iteration.
][0]
// Start with an empty array for the new friends list
, []);
}
// Now we have for each person that connects to Quinn a number:
// { [name1]: number, ... }
// Convert this to a format suitable to output
var result =
// Get list of names from the object (they are the keys)
Object.keys(persons)
// Sort that list of names
.sort()
// Loop over these names to format them
.map(name =>
// Format as "name: distance" or "name: uncool" depending on whether there
// still is an array of friends (object) in this entry
name + ': ' + (typeof persons[name] == 'object' ? 'uncool' : persons[name]));
// Output the result in the console
console.log(result);
And a more verbose, but easier to understand version:
// Get input as text
var input = `10
Alden Toshiko
Che Kortney
Che Dorian
Ronda Lindell
Sharon Alden
Dorian Quinn
Owen Sydnee
Alden Che
Dorian Tyra
Quinn Ally`;
// Build persons list with friends list
// Take the input string
var persons = input;
// Split it by any white-space to get array of words
persons = persons.split(/\s+/)
// Skip the word at position 0: we don't need the line count
persons = persons.slice(1)
// Loop over that array and build an object from it
var obj = {}; // Start loop with an empty object
for (var i = 0; i < persons.length; i++) {
var name = persons[i]; // name = current name in names array
// Get the list of friends we already collected for this name.
// Create it as an empty array if not yet present.
if (obj[name] === undefined) obj[name] = [];
// Add to that list the previous/next name, depending
// whether we are at an odd or even position in the names array
obj[name].push(persons[i%2 === 1 ? i-1 : i+1]);
}
// Assign result to persons
persons = obj;
// Now we have a nice object structure:
// { [name1]: [friendName1,friendName2,...], [name2]: ... }
// Start with Quinn as the only person we currently look at.
var friends = ['Quinn'];
// Increment the distance for each "generation" of friends
// until there are none left.
for (var i = 0; friends.length !== 0; i++) {
// Loop over those friends, building a new list of friends
// Start with an empty array for the new friends list
var newFriends = [];
for (var k = 0; k < friends.length; k++) {
var friend = friends[k];
// Only consider those that still have a friends array (object) assigned to them,
// since the others were already assigned a distance number.
if (typeof persons[friend] === "object") {
// Add this friends' friends to the new list
newFriends = newFriends.concat(persons[friend]);
// ... and then replace this friends' friend list
// by the current distance we are at.
persons[friend] = i;
}
};
// Make the new list the current list:
friends = newFriends;
}
// Now we have for each person that connects to Quinn a number:
// { [name1]: number, ... }
// Convert this to a format suitable to output
// Get list of names from the object (they are the keys)
var result = Object.keys(persons);
// Sort that list of names
result.sort();
// Loop over these names to format them
for (var i = 0; i < result.length; i++) {
var name = result[i];
// Format as "name: distance" or "name: uncool" depending on whether there
// still is an array of friends (object) in this entry
if (typeof persons[name] == 'object') {
result[i] = name + ': uncool';
} else {
result[i] = name + ': ' + persons[name];
}
}
// Output the result in the console
console.log(result);
If i had to solve this problem,
First I would create an array and initialise it with student who are 1 with Quinn by finding rows (elements) studentX ←→ Quinn in original array.
Then I would search recursively those who are level n with quinn by finding rows studentX ←→ student(n-1)FromQuinn
My attempt to understand
var persons = input.split(/\s+/).slice(1).reduce(function(obj,name,i,names){
return (obj[name] = (obj[name] || []).concat([names[i%2 ? i-1 : i+1]]), obj);
},{});
First input.split(/\s+/).slice(1) Gives us an array with all of the names in it.
Now
(obj[name] = (obj[name] || []).concat([names[i%2 ? i-1 : i+1]]), obj);
obj is set by default to due to {} according to the reduce method property.
name is current value which is basically going from Alden all the way to Ally. i will go from 1-10 and names is the array
Now we are saying set obj[name] = obj[name].concat([names[i%2 ? i-1 : i+1]]),obj); IF this is possible. If this isn't possible set obj[name] = [].concat([names[i%2 ? i-1 : i+1]]),obj);. This is my interpretation from reading up on ||
Example iteration
first obj = {}, and name will be Alden
so the type Alden i.e persons = { Alden: ..} will be obj[Alden].concat(names[2],obj), it will be 2, since 1 mod 2 doesn't get reached.
Now there is where I am a bit confused... what exactly is the ,obj doing here..? am I interpreting this right?

Categories

Resources