Extract unique values of a key in a object - Javascript/d3 legend - javascript

Consider the following simplified csv file
x,y,names
1,2,group1
3,2,group2
4,3,group1
7,8,group3
3,5,group2
which I am reading in with d3.csv and afterwards apply a some function on it
d3.csv('file_name.csv').then(data => {
render(dataset)
});
Could someone explain to me how I could extract the unique strings in the category names and store them in a list
---> iam_a_list = [group1, group2, group3]
The elements in this list will later be used as text for a legend in a plot.

You can use a set to get unique results. Just loop over your data and make an array of all the names. Then make a set, which will remove all the duplicates and give you a unique list.
Using .map() and d3.set().values()
let uniqueListOfNames= []
d3.csv('file_name.csv').then(data => {
// listOfNames = ['group1', 'group2', 'group1', 'group3', 'group2']
const listOfNames = data.map(row => row.names)
// uniqueListOfNames = ['group1', 'group2', 'group3']
uniqueListOfNames = d3.set(listOfNames).values()
});
Using a loop.
let uniqueListOfNames= []
d3.csv('file_name.csv').then(data => {
const listOfNames= []
for (const row of data) {
listOfNames.push(row.names)
}
// listOfNames= ['group1', 'group2', 'group1', 'group3', 'group2']
// uniqueListOfNames = ['group1', 'group2', 'group3']
uniqueListOfNames = d3.set(listOfNames).values()
});

Related

Traverse all possible paths of an array with javascipt using async

I' am a begginer with Javascript and I am currently try to find all possible paths of a returned JSON object from an axios GET request.Every item can belong to one or more groups, and one group can belong to an other group.
e.g.
{
"name": "item1",
"groupNames": [ "GROUPA" ]
}
{
"name": "GROUPA",
"groupNames": [
"GROUPB"
]
}
....
{
name: "GROUPZ"
"groupNames": [
]
}
My issue is that my code is working only if a item name has only one parent groupName in the array.
What if we have more than one parentgroupNames? e.g
{
"name": "item1",
"groupNames": [ "GROUPA","GROUC",GROUBD ]
}
...
My current code:
let parent = 'item1';
do{
let endpoint = ${process.env.OPENHAB_HOST}:${process.env.OPENHAB_PORT}/rest/items/${parent}?recursive=false
result = await getAxiosRequest(endpoint,{},res); // get request to specific endpoint
parent = result.data.groupNames; }
while(result.data.groupNames.length !== 0 )
To find all the parent groups for an item that has multiple parent groups, you can modify your code as follows:
Initialize an array called parents to store the parent groups that you find.
In the loop, instead of assigning parent to result.data.groupNames, iterate over result.data.groupNames and add each group to the parents array.
After the loop, parents will contain all the parent groups for the given item.
Here's how the modified code would look:
let parent = 'item1';
let parents = []; // initialize array to store parent groups
do {
let endpoint = `${process.env.OPENHAB_HOST}:${process.env.OPENHAB_PORT}/rest/items/${parent}?recursive=false`;
result = await getAxiosRequest(endpoint,{},res); // get request to specific endpoint
result.data.groupNames.forEach(group => parents.push(group)); // add each group to the parents array
parent = result.data.groupNames;
} while(result.data.groupNames.length !== 0);
console.log(parents); // array of parent groups
This should work even if the item has multiple parent groups.
It is not entirely clear what the end result should be after the loop has ran, but I'll assume you would maybe collect the paths from the given item in an array.
As indeed you can get multiple groups, you need to either store them in a queue/stack for later processing, or use recursion (for the same reason).
Here is how it could look with recursion:
function async visit(parent) {
const endpoint = `${process.env.OPENHAB_HOST}:${process.env.OPENHAB_PORT}/rest/items/${parent}?recursive=false`;
const {data} = await getAxiosRequest(endpoint, {}, res);
const results = [];
for (const group of data.groupNames) {
results.push(...(await visit(group)).map(path => path.concat(group)));
}
return results;
}
visit('item1').then(paths => {
// ....
});

Get max top 10 element in array in javascript

I have an array something like that and I want to sort by population property.
const countries = [
{"name":"Burkina Faso",population:19034397},
{"name":"Burundi",population:10114505}
...
]
Then I want to get top max 10 object with name and property into something like that
const data = {
labels=[<country names>]
datasets:[
{data:[<population numbers>]}
]
}
I tried some code
const sortItem = () => {
let arr =[]
let values = dataSource.map(item => arr.push({name:item.name,population:item.population}))
let topValues = values.sort((a,b) => b.population-a.population);
console.log(topValues) // output 1,2,3,4,5...
}
But I can't get what I want. How can I achieve the solution ?

Get cypress database query output objects in to variables

I have a cypress test which has been set up with mysql node module. When I run bellow mentioned test Its giving output as follows.
const executeQuery = (query) => {
cy.task('DBQuery', query).then(function (recordset) {
var rec = recordset
cy.log(rec)
})
}
Query:
select *
from Users
where email = 'sheeranlymited#lymitedtest.com'
OUTPUT: log [Object{23}]
Query:
select firstname
from Users
where email = 'sheeranlymited#lymitedtest.com'
OUTPUT: log [{firstname: Edward}]
instead of cy.log(rec) I want to get the output of 23 columns to assign in to different variables based on the column name.
Appreciate if someone can help me to resolve this...
You can use Object.values in js to retrieve values from your object
Let's say you need to extract the value of the 3rd column, so your code will look like,
cy.task('DBQuery', query).then(function (recordset) {
var rec = recordset
const results = Object.values(rec[0])
// results[index of the column] will output the results
cy.log(results[3])
})
We can do a small modification to make your task easier,
cy.task('DBQuery', query).then(function (recordset) {
var rec = recordset
const Values = Object.values(rec[0]);
const keys = Object.keys(rec[0]);
let result = {};
let index = 0;
keys.forEach(key => {
result[keys[index]] = Values[index];
i++
})
//result.firstName will give you your results
cy.log(result.firstName);
})
In this way, we are generating key-value pairs having the key as the column name. So you can use the column name to find the value.
Hope this helps.
cheers.

Javascript - How to display SessionStorage obj in HTML

I have object data in sessionStorage and I want to display them as a list in HMTL via loop. How do I Achieve this?
SesionStorage.cart data stringified:
[{"itemName":"WS: FaceShield, 10pcs pack","itemPrice":0,"itemQuantity":"1"},{"itemName":"Faceshield, 1 pc","itemPrice":0,"itemQuantity":"1"}]
What I want to do now is display them on a list after parsing them as JSON Object again.
Say you have
<ul id="myUL"></ul>
Here's a suggestion how to do it in JavaScript by using Array.prototype.reduce into a Web API DocumentFragment that can be later ParentNode.append() -ed into an UL HTMLElement:
// Let's define our array
const arr = [
{"itemName":"WS: FaceShield, 10pcs pack","itemPrice":0,"itemQuantity":"1"},
{"itemName":"Faceshield, 1 pc","itemPrice":0,"itemQuantity":"1"}
];
// Store it into LS...
localStorage.arr = JSON.stringify(arr);
// Read it from LS
const LS_arr = JSON.parse(localStorage.arr);
// Create a helper for new elements...
const ELNew = (sel, attr) => Object.assign(document.createElement(sel), attr || {});
// Loop the array and create LI elements
const LIS = LS_arr.reduce((DF, item) => {
DF.append(ELNew('li', {
textContent: `Name: ${item.itemName} Price: ${item.itemPrice}`
}));
return DF;
}, new DocumentFragment());
// Once our DocumentFragment is populated - Append all at once!
document.querySelector("#myUL").append(LIS);

JS - Pushing data into JSON structure using forEach loops on Arrays

I am attempting to extract JSON values (from structure called jsonWithListOfStatesAndCounters) if it matches with an element in my inputted array (inputedJurisdictionArray). My inputed array contains sting values that include singular or multiple state names (i.e. var inputedJurisdictionArray = ["Iowa", "California, Indiana, Delaware", "Florida"]). The singular State values in this array are handled normally at the end, but the multiple state values is where it gets tricky. I am using split() in order to turn them into another array so they can get processed one by one. Anytime one of the states from this inputed array matches with a "state" value in jsonWithListOfStatesAndCounters, I am extracting it into another JSON structure and pushing it at the end of every block into my initial variable myJurisdictionJSON. The problem I am having is that once these forEach loops are completed, I am still left with my original values in myJurisdictionJSON, instead of the val and counter that should be extracted. The jsonWithListOfStatesAndCounters definitely contains the values that should match with the elements of my inputedJurisdictionArray, but the information is not being pushed into myJurisdictionJSON. What am I doing wrong? Any tips/pointers will be helpful.
var myJurisdictionJSON = [{
jurisdiction_val: 'jurisdiction_val',
jurisdiction_counter: 'jurisdiction_counter'
}];
inputedJurisdictionArray.forEach(function each(item) {
if (Array.isArray(item)) {
item.forEach(each);
} else {
var jurisdictionInput = item;
jsonWithListOfStatesAndCounters.forEach(function each(item) {
if (Array.isArray(item)) {
item.forEach(each);
} else {
if (jurisdictionInput.includes(",") === true){//Checking if more than one jurisdiction in string
var jurisdictionArr = jurisdictionInput.split(", ");
var jurisdictionCounter = item.jurisdictionCounter;
var jurisdictionState = item.jurisdictionState;
jurisdictionArr.forEach(function(element) {
if (myJurisdictionJSON.jurisdiction_counter == 'jurisdiction_counter'){ // If nothing is pushed into our predefined JSON object
if (jurisdictionState.toLowerCase() == trim(element.toLowerCase())) {
var jurisdictionJSON_inner = {
jurisdiction_val: element,
jurisdiction_counter: jurisdictionCounter
};
myJurisdictionJSON.push(jurisdictionJSON_inner);
return;
}
}else if (myJurisdictionJSON.jurisdiction_counter != 'jurisdiction_counter'){ // if an item has been pushed into myJurisdictionJSON, append the next items
var jurisdictionCounter = item.jurisdictionCounter;
var jurisdictionState = item.jurisdictionState;
if (jurisdictionState.toLowerCase() == trim(jurisdictionInput.toLowerCase())) {
jurisdictionJSON_inner.jurisdiction_val = jurisdictionJSON_inner.jurisdiction_val + ", " + jurisdictionInput;
jurisdictionJSON_inner.jurisdiction_counter = jurisdictionJSON_inner.jurisdiction_counter + ", " + jurisdictionCounter;
myJurisdictionJSON.push(jurisdictionJSON_inner);
return;
}
}
});
}
else{// if only one jurisdiction state in jurisdictionInput string
var jurisdictionCounter = item.jurisdictionCounter;
var jurisdictionState = item.jurisdictionState;
if (jurisdictionState.toLowerCase() == trim(jurisdictionInput.toLowerCase())) {
var jurisdictionJSON_inner = {
jurisdiction_val: jurisdictionInput,
jurisdiction_counter: jurisdictionCounter
};
myJurisdictionJSON.push(jurisdictionJSON_inner);
return;
}
}
}
});
I'm not totally sure the output is what you want but it's close.
// input data as per your example
let inputedJurisdictionArray = [
'Iowa',
'California, Indiana, Delaware',
'Florida'
];
// I had to make this part up. It's missing from the example
let jsonWithListOfStatesAndCounters = [{
jurisdictionCounter: 2,
jurisdictionState: 'Florida'
},
{
jurisdictionCounter: 4,
jurisdictionState: 'Indiana'
},
{
jurisdictionCounter: 3,
jurisdictionState: 'Texas'
}
];
// first, fix up inputedJurisdictionArray
// reduce() loops over each array element
// in this case we're actually returning a LARGER
// array instead of a reduced on but this method works
// There's a few things going on here. We split, the current element
// on the ','. Taht gives us an array. We call map() on it.
// this also loops over each value of the array and returns an
// array of the same length. So on each loop, trim() the whitespace
// Then make the accumulator concatenate the current array.
// Fat arrow ( => ) functions return the results when it's one statement.
inputedJurisdictionArray = inputedJurisdictionArray.reduce(
(acc, curr) => acc.concat(curr.split(',').map(el => el.trim())), []
);
// now we can filter() jsonWithListOfStatesAndCounters. Loop through
// each element. If its jurisdictionState property happens to be in
// the inputedJurisdictionArray array, then add it to the
// myJurisdictionJSON array.
let myJurisdictionJSON = jsonWithListOfStatesAndCounters.filter(el =>
inputedJurisdictionArray['includes'](el.jurisdictionState)
);
console.log(myJurisdictionJSON);

Categories

Resources