List array into Javascript array? - javascript

Goal:
Pass the following tweet to visualization tool and display tweet on the UI.
Setup:
I'm getting the following 'List' on my UI. I just want to convert this list to javascript array (so that I can pass it to Visualization tools). I have concat'd 'qqq' for end of every field to identify where it ends.
Tweet:
[*high-pitched yelp* http://t.co/qaluND2Lu3qqq, neutralqqq, 0qqq,
I checked in at Starbucks on #Yelp http://t.co/8wRVos8STjqqq, negativeqqq, -0.159316qqq,
i would like to thank yelp for not helping me find any club around santa monica that plays progressive edm / progressive tranceqqq, positiveqqq, 0.372338qqq,
Nice long bar table & upstairs option (# Social Kitchen & Brewery) on #Yelp http://t.co/uhQB003NTiqqq, positiveqqq, 0.567625qqq]
Question:
How do I split by 'qqq' and then put it in a javascript array?
I have tried doing the following:
var str = "*high-pitched yelp* http://t.co/qaluND2Lu3qqq, neutralqqq, 0qqq";
var res = str.split("qqq");
But the method adds more one comma (,) at the end of every qqq. I'm confused.
Can someone help?

Update 2
It might be best to just build a new clean array, without any undefined values.
var str = "*high-pitched yelp* http://t.co/qaluND2Lu3qqq, neutralqqq, 0qqq",
myArray = str.split('qqq'),
newArray = new Array();
for ( i = 0; i < myArray.length; i++ ) { // Assuming array is built starting with the key 0
// Denote any array element that is undefined, or nonsensical white-space
if ( myArray[i] !== "" && myArray[i] !== undefined && myArray[i] !== " " ) {
newArray.push(myArray[i]);
}
}
myArray = newArray;
console.log(myArray);

Related

Map.delete() not working on key in parent Map

What I'm doing right now, is deleting any diff that doesn't contain the string, and if the diff's dictionary is empty, then i try to delete the map.
the issue here is that, i can't delete a map with data.delete(map) for some reasons (no errors in console) and any piece of code located after that deletion in the if statement won't run.
here is the code in question:
var data = new Map({"593620 Linked Horizon - Shinzou o Sasageyo! [TV Size]": {"difficulties": {"Titan": 86813}}, "859608 LiSA - ADAMAS (TV Size)": {"difficulties": {"Kibbleru's Blue Rose": 899}},"940746 CHiCO with HoneyWorks - Kimi ga Sora Koso Kanashikere": {"difficulties": {"Taeyang's Extra": 72321}}});
var string = "titan";
Array.from(data.keys()).forEach(function(map) {
if (!(map.toLowerCase().indexOf(string.toLowerCase()) >=0)) {
if (document.getElementById("diff_search_box").checked) {
Array.from(data.get(map).get("difficulties").keys()).forEach(function(diff) {
if (!(diff.toLowerCase().indexOf(string) >= 0)) {
data.get(map).get("difficulties").delete(diff)
}
})
if (Array.from(data.get(map).get("difficulties").keys()).length = 0) {
data.delete(map)
}
}
}
})
in this situation, I'm supposed to get a dictionary such as:
{
"593620 Linked Horizon - Shinzou o Sasageyo! [TV Size]": {
"difficulties": {"Titan": 86813}
}
}
Huge number of problems with this code. My recommendation is don't write so much code without running it to make sure it works first. Write small pieces at a time and run it as you go making sure everything works along the way.
Issue number one is you cannot initialize a map with an object like that. The Map must be initialized with an array of arrays that are each two elements long, each containing the key value pairs for the map. You can fix this by wrapping the object in Object.entries() as that will return the key vale pairs for the object.
Second problem is titan is a string so it should be "titan".
Number three, you're calling .get on an object in the line data.get(map).get("difficulties"). Objects do not have .get, you have to use brackets or dot syntax: data.get(map).difficulties or data.get(map).difficulties.
Fourth, I think you don't actually want to delete the data from the map. If you did, when the user changes the search text the old data would still be gone.
Why are you using map anyways? you can simply use a normal object.
Just do this if you must use maps:
var data = new Map(Object.entries({
"593620 Linked Horizon - Shinzou o Sasageyo! [TV Size]": {
"difficulties": {"Titan": 86813}
},
"859608 LiSA - ADAMAS (TV Size)": {
"difficulties": {"Kibbleru's Blue Rose": 899}
},
"940746 CHiCO with HoneyWorks - Kimi ga Sora Koso Kanashikere": {
"difficulties": {"Taeyang's Extra": 72321}
}
}));
var string = 'titan';
function search(s) {
var r = {};
for( const [key, value] of data ) {
for( const diffKey in value.difficulties ) {
if(diffKey.toLowerCase().indexOf(string) != -1)
r[key] = value;
}
}
return new Map(Object.entries(r));
}
With this function, you can do search(string) and it will return you the map that you were wanting originally.
Mainly you should writing a bunch of code without running anything.
Map needs an iterable like an array passed to it such as:
new Map([['Key 1', 'Value 1'], ['Key 1', 'Value 1']])
You can't pass an object literal to it but you can easily use Object.entries() to extract the needed array from your object.
Then you can use Map.prototype.forEach() to loop over all the Map entries
var data = {"593620 Linked Horizon - Shinzou o Sasageyo! [TV Size]": {"difficulties": {"Titan": 86813}}, "859608 LiSA - ADAMAS (TV Size)": {"difficulties": {"Kibbleru's Blue Rose": 899}},"940746 CHiCO with HoneyWorks - Kimi ga Sora Koso Kanashikere": {"difficulties": {"Taeyang's Extra": 72321}}};
const map = new Map(Object.entries(data));
map.forEach((value, key) =>{
const {difficulties} = value;
console.log('Map key:', key.toLowerCase());
// if(someCondition){
// map.delete(key)
// }
Object.entries(difficulties).forEach(([k,v])=>{
console.log('Diff key:', k, ' Diff value:', v)
// if(k.toLowerCase().includes('titan')){
// delete difficulties[key];
// }
})
console.log('*****************************')
})
surprising to see none of the previous answer saw that, another person on a discord server i do support for software stuff on pointed out the last if condition and the fact it's missing a = so it appear as
if (Array.from(data.get(map).get("difficulties").keys()).length == 0) {
// was = before, == now
data.delete(map)
}
so now i indeed obtain a data dictionary with only 1 element containing the map which also have the difficulty that's contained in the specified string.

How do you map an object from a transposed/inverted range that is able to perform key-value lookups in GAS?

I'm scripting a custom function() that needs to display a specific key-value from a range named ioRange that consists of cells "A1:B3" shown below.
// google sheets ui
/*
[A] [B]
[1] || ID || 1 ||
[2] || NAME || Elon ||
[3] || EMOJI || 🚀 ||
*/
From what I’ve gathered so far, this kind of key-value table structure is no good for google sheets to process cleanly. For instance, with the cells above, google scripts kind of creates a pseudo associative array as a range, but formatted with google scripts row brackets and other nuances like quotes:
var ioRange = ss.getRange("A1:B3").getValues()
console.log(ioRange)
// => "[[ID, 1], [NAME, Elon], [EMOJI, 🚀]]"
I’m currently stuck on converting ioRange into a key-value mapped object named ioObject, having issues with push() -ing new values to ioObject in the correct format. Below is my bad code, but hopefully it gives an idea of what I’m trying to accomplish.
// 👾 bad code
var ioObject = {}
for (row = 0; row < ioRange.length; ++row) {
ioObject.push(`${ioRange[row][0]}: "${ioRange[row][1]} as"`)
}
I want the ioObject to result in this output:
// 🏁 desired output
console.log(JSON.stringify(ioObject))
/* => '{
"ID": "1",
"NAME": "Elon",
"EMOJI": "🚀"
}'
*/
So that I can do key-value lookups like this:
// 😀 success!
console.log(ioObject["NAME"])
// => "Elon"
I checked out javascript - Creating hash array in Google Apps Script - Stack Overflow and Hash Tables in Javascript but no luck.
SOLUTION:
// ✅ solved w/ escaping double quotes
var ioObject = {}
for (row = 0; row < ioRange.length; ++row) {
ioObject[ioRange[io][0]]=ioRange[io][1]
}
console.log(JSON.stringify(ioObject))
// => '{"ID"="1", "NAME"="Elon", "EMOJI"="🚀"}'
// 😀 success!
console.log(ioObject["NAME"])
// => "Elon"

Efficient way to search within multiple values in json

I have multiple records like this,
name: John Doe aliases: John, Doe, JD unique_id: 1 ...
My question is how do I search efficiently within the aliases & full name.
If the search query is any of those 4 (John Doe, John, Doe, JD) I would like to find the unique id (in this case 1).
What I have done: I have a very straightforward implementation that loops through the entire data until it finds. It takes a long time since the number of fields is very high.
Note: I am using javascript if it helps. Also I have the permission to change the data format (permanently), if it will make the search more efficient. Most of the search queries tend to be one of the aliases rather than full name.
Sample Code: https://jsfiddle.net/nh7yqafh/
function SearchJSON(json, query) {
var champs = json.champs;
for (var i = 0; i < champs.length; ++i) {
if (query == champs[i].name)
return champs[i].unique_id;
for (var j = 0; j < champs[i].aliases.length; ++j) {
if (query == champs[i].aliases[j])
return champs[i].unique_id;
}
}
}
//Data format is similar to what vivick said
var json_string = '{"count":5,"champs":[{"name":"Abomination","aliases":["abomination","AB","ABO"],"unique_id":1},{"name":"Black Bolt","aliases":["blackbolt","BB","BBT"],"unique_id":2},{"name":"Black Panther","aliases":["blackpanther","BP","BPR"],"unique_id":3},{"name":"Captain America","aliases":["captainamerica","CA","CAP"],"unique_id":4}]}'
var json = JSON.parse(json_string);
query="CA";
alert( "id of "+query+" is "+SearchJSON(json, query));
I guess you have a structure similar to the following one :
[
{
"name": "xxx",
"aliases": ["x", "xx", "xxx"],
"unique_id": 1,
/* [...] */
},
/* [...] */
]
You can then do something like this :
const queryParam = /*search query*/;
const arr = /* get the JSON record */;
const IDs = arr
.filter( entry =>(entry.aliases.includes(queryParam) || queryParam===entry.name) )
.map(entry=>entry.uniqueId);
This will give you an array of IDs which are potential matches.
If you need either 0 or 1 result only :
const ID = IDs[0] || null;
This will simply retrieve the first matched ID if there's one, otherwise it will set ID to null.
NB:
If you use an object of objects instead of an array of object, there's just a little bit of modifications to do (mainly using Object.entries) but it still is trivial.
PS:
I would recommend to always add the full name in the aliases, this will ease the filtering part (no || would be required).

resolving a javascript and database table logic situation

When I query a database table, I get back values "yes" or "no" for records that represent whether an item is present or not (the item is the column name). I want to create a string that represents the products that are available by name (rather than what I am doing now "kitchen table =" + kitchenTable;
I am thinking this can be solved (poorly) by a series of if statements setting variables to either the product name or to "" and then include all variables in the string
var kt;
if (kitchenTable == yes) kt = "kitchen table";
else kt = "";
if (kitchenCabinet == yes) kc = "kitchen cabinet";
else ka = "";
output = kt + ', ' + kc;
There are about 50 items that can be presented to the user, is there a more efficient way of accomplishing this task?? One option is to change how values are entered into the datbase table such that instead of yes, its the item name but this seems like a poorer way to resolve the issue
Of course you don't give all the details about how do you make query so that is an imaginary mockup of a function simulating query
var available = [];
var result = query("kitchen table");
result === "yes" && ( available.push("kitchen table") );
......
var output = available.join();
What you want is actually built into javascript itself.
I would say using an object literal will really simply your life in this situation by organizing your code and turning it into a more readable format.
I would also recommend turning your server data into true and false as this is a standardized way to communicated a Boolean and allows for the method below to work as it does:
// From server response
var results = {
kitchenCabinet: true,
kitchenTable: true
}
// Use this for your storage of all related items
var kitchenProps = {
kitchenCabinet: 'kitchen cabinet',
kitchenTable: 'kitchen table'
}
// Reuse this function for each time your need a new category (masterBathroomProps...)
function getItemDataIfExists(results, hashTable){
'use strict';
var output = 'Your total is: ';
for (var item in results) {
if (!results.hasOwnProperty(item)) return;
if (results[item]) output += 'A '+hashTable[item]+' ';
}
return output;
}
getItemDataIfExists(results, kitchenProps);
Explanation:
You loop through a result set of an object containing keys names and true false values. In the loop, if the keyname's value is true, then use that keyname to access the properties (in this case a string of your choice. The "key" here is that the key names in each object must line up.
Here is a live demo:
http://codepen.io/nicholasabrams/pen/JXXbYz?editors=0010

JavaScript database correlation

I've been trying to 'correlate' between user picked answers and an object property name so that if the two matches then it will display what is inside.
My program is a recipe finder that gives back a recipe that consists of the ingredients the user picked.
my code currently looks like:
//property are the ingredients and the value are the recipes that contain those ingredients. The map is automatically generated
``var map = {
"pork" : [recipe1, recipe2, ...],
"beef" : [],
"chicken" :[],
}
//this gets the user pick from the dom
var cucumber = specificVegetable[7];
var lemon = specificFruits[0];
//Then this code finds the intersection of the recipe(recipes that use more than one ingredients)
function intersect(array1, array2)
{
return array1.filter(function(n) {
return array2.indexOf(n) != -1
});
}
var recipiesWithLemon = map["lemon"]; **// makes the lemon object is map**
var recipiesWithCucumber = map["cucumber"]; **// makes the cucumber object in map**
//Here is where I am stuck
function check(){
var both = intersect(recipiesWithLemon, recipiesWithCucumber);
if ( cucumber.checked && lemon.checked){
for (var stuff in map){
if(stuff="cucumber" && stuff="lemon"){
return both;
}
}
}
}
check();
so basically what I tried to do was I made my intersect and then if user pick is lemon and cucumber then look at the properties in the map object. if the name of the property equals to the exact string then return both. That was the plan but the code does not work and I'm not sure how to fix it.
My plan is to write code for every possible outcome the user may makes so I need to find the correlation between the user pick and the map which stores the recipe. I realize this is not the most effective way but I'm stumped on how to do it another way.
Thanks for the help.
Im using the open source project jinqJs to simplify the process.
I also changed your map to an array of JSON objects. If you must have the map object not as an array, let me know. I will change the sample code.
var map = [
{"pork" : ['recipe1', 'recipe2']},
{"beef" : ['recipe3', 'recipe4']},
{"peach" :['recipe5', 'recipe6']},
{"carrot" :['recipe7', 'recipe8']}
];
var selectedFruit = 'peach';
var selectedVeggie = 'carrot';
var selections = [selectedFruit, selectedVeggie];
var result = jinqJs().from(map).where(function(row){
for(var f in row) {
if (selections.indexOf(f) > -1)
return true;
}
return false;
}).select();
document.body.innerHTML += '<pre>' + JSON.stringify(result, null, 2) + '</pre><br><br>';
<script src="https://rawgit.com/fordth/jinqJs/master/jinqjs.js"></script>

Categories

Resources