I am reading data from a text file and I am interested in a specific pattern that I have isolated with the following:
cleanString = queryString.match(/^NL.*/gm);
This results in the array:
["NL:What are the capitals of the states that border the most populated states?",
"NL:What are the capitals of states bordering New York?",
"NL:Show the state capitals and populations.",
"NL:Show the average of state populations.",
"NL:Show all platforms of Salute generated from NAIs with no go mobility."]
I then want to get rid of all patterns matching NL: so I am left with just a natural language question or statement. To accomplish this, I convert the array to a string , and then use .split() to create the desired array like so:
var nlString = cleanString.toString();
var finalArray = nlString.split(/NL:/gm);
There are two problems I am having.
1. I end up with an extra value of an empty string at index [0] in the resulting array, and
2. I now have a comma literal appended to the strings in the array:
["", "What are the capitals of the states that border the most populated states?,",
"What are the capitals of states bordering New York?,",
"Show the state capitals and populations.,",
"Show the average of state populations.,",
"Show all platforms of Salute generated from NAIs with no go mobility."]
How can I eliminate these problems? Also If someone has a more elegant approach to reading a big ugly text file delimited by line breaks and isolating strings of interest I am all eyes.
Thanks in advance for any suggestions.
You don't have to convert the array to a string, then remove the NL: strings and convert back to an array, just iterate over the array and remove that string in each index
var arr = arr.map(function(el) {return el.replace('NL:','');});
FIDDLE
a regular for loop would also work if older browsers is an issue
var finalString = nlString.replace(/NL:/gm, '');
Warning : map is not supported by IE8 and below. Here is an alternative :
var array = string.split(/\n*NL:/);
array.shift(); // that's it
Demo here : http://jsfiddle.net/wared/BYgLd/.
Related
I use Zapier to automate many of our business functions, which is great, but I got stuck trying to count the number of arrays or, if you like, a particular word pattern that comes from a string. I can tidy up the string with Zapier formatter, but cannot figure out how to carry out a count.
Here is an example of a tidied string where " have been removed:
[{Name:Jon,Surname:Smith},{Name:David,Surname:Michael},{Name:Sam,Surname:Fields},{Name:Katy,Surname:Milnes}]
In this instance I would want the count on say "Name" to return 4.
I have looked at different code examples for counting words but cannot execute them correctly in the code action of Zapier. This is probably really straight forward but I do not come from a coding background so a simple Java (or Python) script to drop into the Zapier code action or some pointers on how to solve this would be greatly appreciated.
Thanks
What are you really trying to achieve by trying to count the word?
Do you just want to know the number of objects the array contains? If that is the case something like this would work. Assuming that the array is in your inputData for the code step.
var data = JSON.stringify([{'Name':'Jon', 'Surname':'Smith'},{'Name':'David','Surname':'Michael'},{'Name':'Sam','Surname':'Fields'},{'Name':'Katy','Surname':'Milnes'}]);
var inputData = {objArr: data};
// Do not insert the above lines in your code step.
// Set the objArr to your array in the inputData step.
var parsedObjArr = JSON.parse(inputData.objArr);
// Skip the above step if the array is not in the inputData object.
var arrLen = parsedObjArr.length
console.log('Array Length: ', arrLen);
// The line below outputs data from the code step.
output = {arrLen}
Also note, you do not need to remove the quotes from the JSON string.
If the array is not in the inputData of the code step, you can just directly use the length method on the array.
Well in Python you can convert the json string into dictionary with key as the name. Length of dictionary is what you are looking for. Here is the example:
import json
from collections import defaultdict
d=defaultdict(list)
x=json.dumps([{'Name':'Jon', 'Surname':'Smith'},{'Name':'David','Surname':'Michael'},{'Name':'Sam','Surname':'Fields'},{'Name':'Katy','Surname':'Milnes'}])
json_string=json.loads(x)
for obj in json_string:
if(obj['Name'] in d):
d[obj['Name']].append([obj['Name']+' '+obj['Surname']])
else:
d[obj['Name']]=[obj['Name']+' '+obj['Surname']]
print(len(d))
I need to dynamically create a multidimensional javascript array that matches this layout:
array_answers[0][1]:"yes"
array_answers[1][2]:"no"
array_answers[2][2-subquestion]:"text input"
array_answers[3][8]:"yes"
array_answers[4][8-subquestion]:"text input"
The first "[ ]" defines what question it is on the page (out of totalInputs)
The second "[ ]" defines what question from the database this is (questions already in order to match the corresponding input)
and the information following is the input I am trying to add
I have attempted to the following with no luck.
for(var i = 0; i < totalInputs; i++) {
array_answers.push([i]);
array_answers[i].push([questions[i]]);
array_answers[i][0] = "yes, no, or other text";
}
The last line is where it falls apart. It would make sense to me that I should be able to use [0] to indicate that I want the first array to be given this value but with no avail.
I have also tried:
for(var i = 0; i < totalInputs; i++) {
array_answers.push([i]);
array_answers[i].push([questions[i]]);
array_answers[i][questions[i]] = "yes, no, or other text";
}
but this gives me lots of empty arrays for all the numbers from 0 to whatever the value of questions[i] is.
What am I missing or is there a simpler way to do this in jQuery while still conforming to the target layout?
If I understand you correctly, you are trying to store questions and prompts (maybe?) together in a multi dimensional array. let me suggest a different way that should work.
const array_answers = questions.map(q => [q, "yes, no, other text"]);
This may be what you want
I am still not 100% sure of what you need, but i thought I would write an answer with my assumptions, that I can update as the information improves.
The first "[ ]" defines what question it is on the page (out of
totalInputs)
This part looks like you are correct, and need to use an array. But an array is just a list of "things", in your case, questions. So where you have this line:
array_answers.push([i]);
I'm not sure it is doing what you are expecting. This is adding a new array item, which is in itself an array, that contains a single number. So if totalInputs is 3, then that first line will result in this structure:
array_answers= [[0],[1],[2]]
I think what you actually might intend here is to simply house an array of question details. Now by the complexity of your keys listed for the second dimension, it looks like an object would be more appropriate.
The second "[ ]" defines what question from the database this is
(questions already in order to match the corresponding input)
So lets go ahead and create a single question.
var question = {
anythingYouWant: 'here',
2: 'even numeric keys'
}
// you can access the values in these ways
console.log(question.anythingYouWant)
console.log(question[2])
console.log(question['anythingYouWant'])
Now once you have a question object, you can then add it to your array_answers array with push.
array_answers.push(question).
If you have two identical questions like the one above, your array will look like this:
array_answers = [{
anythingYouWant: 'here',
2: 'even numeric keys'
},{
anythingYouWant: 'here',
2: 'even numeric keys'
}]
In order to access the questions within the array, you can simply use their index:
// access second question
var secondQuestion = array_answers[1]
You can read these links to learn more about objects & arrays
I'm trying to generate a google form that has a few hundred options in a drop down.
I have all the name values in a single cell formatted as follows:
'user1','user2','user3'
It is set as in the code as follows:
var studentNames = SpreadsheetApp.openById('REDACTED').getSheetByName('Student List').getRange(3,3).getValues();
When I use this variable as shown below it treats it all as a singe value instead of an array.
.setChoiceValues([studentNames])
Any help in where to go from here?
is it a string of words with single quotes and a comma to separate them? if so, you can just do a split on the comma
var s = data
var arr = s.split(",");
and now you will have an array of strings. not sure if this answers your question.
Thanks everyone for getting me pointed in the right direction.
Turns out split was just part of the answer, I had to turn it into a string first.
.toString().split(",");
getValues() returns an object, so you need to interact with it to get the string of values for your array.
Given you are selecting just one cell and so don't need to iterate through the object, try something like this:
var studentNamesObj = SpreadsheetApp.openById('REDACTED').getSheetByName('Student List').getRange(3,3).getValues();
var studentNames = studentNamesObj[0][0].split(",");
I have an array of Strings in JavaScript. I am trying to develop a function that
Takes a substring as an input.
Searches through the array.
Returns strings from the array close to the substring. The list will be provided as suggestions to the caller.
For example:-
Array contains the below entries.
Hello
What is hello
World
Spacearenotthereinthishello
HELLO
Highway to hell
JavaScript
StackOverflow
I invoke the function as shown below
var result[] = searchFunc('hell');
The result array should contain
Hello
What is hello
Spacearenotthereinthishello
HELLO
Highway to hell
It is possible that the array could contain atleast 100 strings ( or more). I am looking for a scalable solution.
Initially, i figured i should sort and then do a binary search but its cumbersome to do if you wanna pull of all the suggestions from the master array for a particular string input. I am looking for algorithms that can help me achieve a faster search. I am not that worried about insertion timecomplexity in master array.
I did look up multiple stack overflow posts. They do speak about searching a big book for specific strings. None of them talk about returning suggestions from an array for a substring.
Your help is appreciated.
YourArray.filter() will do the job. Quick prototype:
var results = arrayName.filter(function(value) {
return value.toLowerCase().indexOf(searchStr.toLowerCase()) >= 0;
});
Quick Answer (TL;DR)
Use Array.prototype.filter()
Detailed Answer
Context
Javascript
Array filtering
Problem
Scenario: Developer wishes to filter an array for matches on a substring
Solution
// declare array of string fragments
myArrayOfStringFragments = /* TODO: get the content [ ... ] */
// optional step, normalize all strings to lower-case
/* TODO: input normalization with Array.prototype.map() or something similar */
// declare comparison function
function strContainsMatch(slookfor) {
return slookfor.includes("ello");
}
// iterate using Array.prototype.filter()
var filtered = myArrayOfStringFragments.filter(strContainsMatch);
Pitfalls
Data input normalization (are differences based on letter-case significant?)
string comparison based on non-ascii characters
string.includes() method may not be available, instead use string.indexOf()
avoiding false-postive matches based on chosen substring
(e.g., if you are looking for hello then hell will match more than you want, and it will miss Hello if your input is not normalized to lowercase)
See also
How can I only keep items of an array that match a certain condition?
Alternate solution would be to create a regex to do the same.
var condition = new RegExp("hell", 'g');
var results = arrayName.filter(function(value) {
return condition.test(value.toLowerCase())
});
Is there any way efficiently to join JSON data? Suppose we have two JSON datasets:
{"COLORS":[[1,red],[2,yellow],[3,orange]]}
{"FRUITS":[[1,apple],[2,banana],[3,orange]]}
And I want to turn this into the following client side:
{"NEW_FRUITS":[[1,apple,red],[2,banana,yellow],[3,orange,orange]]}
Keep in mind there will be thousands of records here with much more complex data structures. jQuery and vanilla javascript are both fine. Also keep in mind that there may be colors without fruits and fruits without colors.
NOTE: For the sake of simplicity, let's say that the two datasets are both in the same order, but the second dataset may have gaps.
Alasql JavaScript SQL library does exactly what you need in one line:
<script src="alasql.min.js"></script>
<script>
var data = { COLORS: [[1,"red"],[2,"yellow"],[3,"orange"]],
FRUITS: [[1,"apple"],[2,"banana"],[3,"orange"]]};
data.NEW_FRUITS = alasql('SELECT MATRIX COLORS.[0], COLORS.[1], FRUITS.[1] AS [2] \
FROM ? AS COLORS JOIN ? AS FRUITS ON COLORS.[0] = FRUITS.[0]',
[data.COLORS, data.FRUITS]);
</script>
You can play with this example in jsFiddle.
This is a SQL expression, where:
SELECT - select operator
MATRIX - modifier, whci converts resultset from array of objects to array of arrays
COLORS.[0] - first column of COLORS array, etc.
FRUITS.1 AS 2 - the second column of array FRUITS will be stored as third column in resulting recordset
FROM ? AS COLORS - data array from parameters named COLORS in SQL statement
JOIN ? ON ... - join
[data.COLORS, data.FRUITS] - parameters with data arrays
The fact that there will be thousands of inputs and the keys are not necessarily ordered means your best bet (at least for large objects) is to sort by key first. For objects of size less than about 5 or so, a brute-force n^2 approach should suffice.
Then you can write out the result by walking through the two arrays in parallel, appending new "records" to your output as you go. This sort-then-merge idea is a relatively powerful one and is used frequently. If you do not want to sort first, you can add elements to a priority queue, merging as you go. The sort-then-merge approach is conceptually simpler to code perhaps; if performance matters you should do some profiling.
For colors-without-fruits and fruits-without-colors, I assume writing null for the missing value is sufficient. If the same key appears more than once in either color or fruit, you can either choose one arbitrarily, or throw an exception.
ADDENDUM I did a fiddle as well: http://jsfiddle.net/LuLMz/. It makes no assumptions on the order of the keys nor any assumptions on the relative lengths of the arrays. The only assumptions are the names of the fields and the fact that each subarray has two elements.
There is not a direct way, but you can write logic to get a combined object like this. Since "apple, red, banana...." are all strings, they should be wrapped in a single or double quote.
If you can match the COLORS and FRUITS config array by adding null values for missing items then you can use this approach.
Working demo
var colors = {"COLORS":[[1,'red'],[2,'yellow'],[3,'orange']]}
var fruits = {"FRUITS":[[1,'apple'],[2,'banana'],[3,'orange']]}
var newFruits = {"NEW_FRUITS": [] }
//Just to make sure both arrays are the same size, otherwise the logic will break
if(colors.COLORS.length == fruits.FRUITS.length){
var temp;
$.each(fruits.FRUITS, function(i){
temp = this;
temp.push(colors.COLORS[i][2]);
newFruits.NEW_FRUITS.push(temp);
});
}
Alternatively, if you can create colors and fruits configs as an array of objects, instead of an array of arrays, you can try this solution. The sequence of the elements is irrelevant here, but the array size should still match.
Working demo
var colors = {"COLORS":[ {"1": 'red'}, { "2": 'yellow'}, {"3":'orange'}]}
var fruits = {"FRUITS":[ {"1":'apple'}, { "2": 'banana'}, {"3":'orange'}]}
var newFruits = {"NEW_FRUITS": [] }
if(colors.COLORS.length == fruits.FRUITS.length){
var temp, first;
$.each(fruits.FRUITS, function(i){
for(first in this)break;
temp = {};
temp[first] = [];
temp[first].push(this[first]);
temp[first].push(colors.COLORS[i][first]);
newFruits.NEW_FRUITS.push(temp);
});
}