I have a google sheet with some data in a single column.
How to assign these values to new object like {'value[0]':value[0], 'value[1]':value[1],..., 'value[i]':value[i]}?
I wrote this script, but it assigns pair from last value of names only:
function getIngredientsList() {
const url = "SPREADSHEET_URL";
const ss = SpreadsheetApp.openByUrl(url);
const ws = ss.getSheetByName('Base');
const names = ws.getRange(2, 3, ws.getLastRow() - 1).getValues().map(a => a[0]);
let nameList;
for (let i = 0; i < names.length; i++){
if (names[i] !== ""){
let name = {[names[i]]:names[i]};
nameList = Object.assign(name);
}
}
return nameList;
}
Where I'm wrong and how to fix it?
I believe your goal as follows.
You want to retrieve the values from the cells "C2:C28", and want to create an object that the key and value are the same.
For this, how about this modification? The arguments of Object.assign() is Object.assign(target, ...sources). So in your script, nameList of let nameList = {} is required to be used like nameList = Object.assign(nameList, name).
From:
let nameList;
for (let i = 0; i < names.length; i++){
if (names[i] !== ""){
let name = {[names[i]]:names[i]};
nameList = Object.assign(name);
}
}
To:
let nameList = {}; // Modified
for (let i = 0; i < names.length; i++){
if (names[i] !== ""){
let name = {[names[i]]:names[i]};
nameList = Object.assign(nameList, name); // Modified
}
}
Or, as other pattern, when reduce is used, the following script can also return the same value with above modified script.
const nameList = ws.getRange(2, 3, ws.getLastRow() - 1).getValues()
.reduce((o, [e]) => {
if (e != "") Object.assign(o, {[e]: e});
return o;
}, {});
Reference:
Object.assign()
More cleaner way to do that is using reduce method:
var names = ['ABC', 'XYZ', 'PQR'];
var result = names.reduce((acc, elem)=>{
acc[elem] = elem;
return acc;
},{});
console.log(result);
Related
I have searched all day on stack overflow and google and can't find the exact thing I need. I have an array of email addresses i will get from the user. Ex. [asdfgg#gmail.com, fgtrreds#yahoo.com, dgfit#gmail.com]. I am wanting to split all of the email addresses and then push just the [#gmail.com, #yahoo.com], etc. to a new array.
Here is a JavaScript function I have been messing with all day
function EmailFunction() {
var emailNames = [];
var emailDomains = [];
emailNames = $("#emailing").val();
var len = emailNames.length;
for (var i = 0; i < len; i++) {
var domain = emailNames.split("#").pop();
emailDomains.push(domain);
}
console.log("Email Domains = " + domain);
console.log("Function Names = " + emailNames);
}
You were missing to add [i] before the emailNames just do it like the following
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
function EmailFunction() {
var emailNames = [];
var emailDomains = [];
emailNames = ['asdfgg#gmail.com', 'fgtrreds#yahoo.com', 'dgfit#gmail.com']
var len = emailNames.length;
for (var i = 0; i < len; i++) {
var domain = emailNames[i].split("#").pop();
emailDomains.push(domain)
var unique = emailDomains.filter(onlyUnique);
}
console.log(unique)
}
EmailFunction()
I give only unique domains as result. For this I iterate with foreach, get the domain (inclusive #) with substr and indexof, look if it's in the resultarray. If not push it there.
function getDomains(mailings) {
let result = [];
mailings.forEach(mail => {
let domain = mail.substr(mail.indexOf('#'));
if (result.indexOf(domain) == -1)
result.push(domain);
});
return result;
}
let mailings = ['asdfgg#gmail.com', 'fgtrreds#yahoo.com', 'dgfit#gmail.com'];
console.log(getDomains(mailings));
Since you don't want duplicates in the final list, you can do it like this
const emailNames = ['asdfgg#gmail.com', 'fgtrreds#yahoo.com', 'dgfit#gmail.com'];
car emailDomains = [];
for(let i=0; i < emailNames.length; i++) {
let domain = emailNames[i].split("#")[1];
if(emailDomains.imdexOf(domain) == -1) {
emailDomains.push(domain);
}
}
console.log(emailDomains);
You can do it with just one line
const emailNames = ['asdfgg#gmail.com', 'fgtrreds#yahoo.com', 'dgfit#gmail.com'];
const result = Object.keys(emailNames.map(e => e.split("#")[1]).reduce((o, e) => ({ ...o, [e]: null }), {}));
console.log(result);
Here is the problem:
Given two strings, find the number of common characters between them.
For s1 = "aabcc" and s2 = "adcaa", the output should be 3.
I have written this code :
function commonCharacterCount(s1, s2) {
var count = 0;
var str = "";
for (var i = 0; i < s1.length; i++) {
if (s2.indexOf(s1[i]) > -1 && str.indexOf(s1[i]) == -1) {
count++;
str.concat(s1[i])
}
}
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
It doesn't give the right answer, I wanna know where I am wrong?
There are other more efficient answers, but this answer is easier to understand. This loops through the first string, and checks if the second string contains that value. If it does, count increases and that element from s2 is removed to prevent duplicates.
function commonCharacterCount(s1, s2) {
var count = 0;
s1 = Array.from(s1);
s2 = Array.from(s2);
s1.forEach(e => {
if (s2.includes(e)) {
count++;
s2.splice(s2.indexOf(e), 1);
}
});
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
You can do that in following steps:
Create a function that return an object. With keys as letters and count as values
Get that count object of your both strings in the main function
Iterate through any of the object using for..in
Check other object have the key of first object.
If it have add the least one to count using Math.min()
let s1 = "aabcc"
let s2 = "adcaa"
function countChars(arr){
let obj = {};
arr.forEach(i => obj[i] ? obj[i]++ : obj[i] = 1);
return obj;
}
function common([...s1],[...s2]){
s1 = countChars(s1);
s2 = countChars(s2);
let count = 0;
for(let key in s1){
if(s2[key]) count += Math.min(s1[key],s2[key]);
}
return count
}
console.log(common(s1,s2))
After posting the question, i found that i havent looked the example well. i thought it wants unique common characters ..
and i changed it and now its right
function commonCharacterCount(s1, s2) {
var count = 0;
var str="";
for(var i=0; i<s1.length ; i++){
if(s2.indexOf(s1[i])>-1){
count++;
s2=s2.replace(s1[i],'');
}
}
return count;
}
Create 2 objects containing characters and their count for strings s1
and s2
Count the common keys in 2 objects and return count - Sum the common keys with minimum count in two strings
O(n) - time and O(n) - space complexities
function commonCharacterCount(s1, s2) {
let obj1 = {}
let obj2 = {}
for(let char of s1){
if(!obj1[char]) {
obj1[char] = 1
} else
obj1[char]++
}
for(let char of s2){
if(!obj2[char]) {
obj2[char] = 1
} else
obj2[char]++
}
console.log(obj1,obj2)
let count = 0
for(let key in obj1 ){
if(obj2[key])
count += Math.min(obj1[key],obj2[key])
}
return count
}
I think it would be a easier way to understand. :)
function commonCharacterCount(s1: string, s2: string): number {
let vs1 = [];
let vs2 = [];
let counter = 0;
vs1 = Array.from(s1);
vs2 = Array.from(s2);
vs1.sort();
vs2.sort();
let match_char = [];
for(let i = 0; i < vs1.length; i++){
for(let j = 0; j < vs2.length; j++){
if(vs1[i] == vs2[j]){
match_char.push(vs1[i]);
vs2.splice(j, 1);
break;
}
}
}
return match_char.length;
}
JavaScript ES6 clean solution. Use for...of loop and includes method.
var commonCharacterCount = (s1, s2) => {
const result = [];
const reference = [...s1];
let str = s2;
for (const letter of reference) {
if (str.includes(letter)) {
result.push(letter);
str = str.replace(letter, '');
}
}
// ['a', 'a', 'c'];
return result.length;
};
// Test:
console.log(commonCharacterCount('aabcc', 'adcaa'));
console.log(commonCharacterCount('abcd', 'aad'));
console.log(commonCharacterCount('geeksforgeeks', 'platformforgeeks'));
Cause .concat does not mutate the string called on, but it returns a new one, do:
str = str.concat(s1[i]);
or just
str += s1[i];
You can store the frequencies of each of the characters and go over this map (char->frequency) and find the common ones.
function common(a, b) {
const m1 = {};
const m2 = {};
let count = 0;
for (const c of a) m1[c] = m1[c] ? m1[c]+1 : 1;
for (const c of b) m2[c] = m2[c] ? m2[c]+1 : 1;
for (const c of Object.keys(m1)) if (m2[c]) count += Math.min(m1[c], m2[c]);
return count;
}
I have a loop that has a function inside. my target here is to check if the current data inside the loop are still the same for example my array is like this
var data = ['test1','test1','test1','test2'];
now I will check them if the data on that array inside the loop are currently the same. for example like this.
for (var i = 0; i < data.length; i++) {
var value = data[i][0];
console.log(checkifcurrent(value));
}
my problem here is to return checkifcurrent(value) if it still the same like this
function checkifcurrent(value) {
if (currentvalue is still the same as the last one) {
console.log(same);
} else {
console.log(not same);
}
}
I hope you understand tysm for understanding
You can do it like this, no need for a function call.
var data = ['test1','test1','test1','test2'];
lastValue = data[0];
for (var i = 1; i < data.length; i++) {
var currentValue = data[i];
if(lastValue==currentValue){
console.log("Value is same")
}
else
{
console.log("Value is not same")
}
lastValue = currentValue;
}
you can iterate over the data array and compare with all the array elements except the one at the current position.
If it is equals to the current and the index is not the same of the current then it is a duplicate
var data = ['test1','test1','test1','test2'];
for (var i = 0; i < data.length; i++) {
var value = data[i];
for(var j = 0; j < data.length; j++){
//skip the index at position i, because it is the one we are currently comparing
if(i !== j && data[j] === value) {
console.log('another value like: ' + value + ' at position: ' + i + ' has been found at index: ' + j)
}
}
}
Its not very clear about your task, i hope it is checking if the a value present in arr1 is available are not in arr2. If you so,
Loop through all elements in arr1 and check the indexof it
arr1 =[1,2,3,4];
arr2 = [2,3,4,5,6,6];
arr1.forEach((x)=>{if(arr2.indexOf(x)==-1){console.log('unable to find the element'+x)}})
unable to find the element1
var isSame = (function () {
var previous;
return function(value){
var result = value === previous;
previous = value;
return result;
}
})();
Alternatively you can use lodash difference function to compare old and new array.
http://devdocs.io/lodash~4/index#difference
For example:
const _ = require('lodash')
// Save the old array somewhere
let oldArray = ['test1','test1','test1','test2']
let newArray = ['test1','test1','test1','test3']
const areParametersTheSame = !!(_.difference(oldArray, newArray))
I want to set multiple keys of array in javascript ,
but code like this was so ugly. but only this can work right.
var listData = [];
listData['today'] = [];
listData['data1'] = [];
listData['data2'] = [];
listData['data3'] = [];
listData['data4'] = [];
listData['data5'] = [];
listData['data6'] = [];
listData['data6'] = [];
i try this to init array
function initArray(arr, keys, defaultValue) {
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
delete arr[key];
arr[key] = defaultValue;
}
return arr;
}
But after setting the array,
i put data in it by
listData['data1'].push(datalist[i].num)
listData['data2'].push(datalist[i].num)
.
returns all the same data1 and data2 in array.
hope someone can help about this batch add keys to array.
Try modifying this push method.
var listData = [];
var keys = [ 'today', 'data', 'daata' ];
initObject(keys);
function initObject(params) {
for (i=0; i<params.length; i++) {
var x = params[i]
listData.push(x)
}
}
Use an object instead of an array:
var listData = {};
var keys = ['today', 'data1', 'data2'];
function initObject(obj, keys, defaultValue) {
keys.forEach(key => {
obj[key] = [];
})
return obj;
}
console.log(initObject(listData, keys, []));
I have a string like this:
var str = 'My_Type_1=SSD&My_Value_1=16GB&My_Category_1=Disk Capacity&My_Type_2=Sony
&My_Value_2=PS4&My_Category_2=Console&My_rowOrder=2,1';
The string mostly has 3 parts except the last key:
Part 1 -> My - is a Common Prefix
Part 2 -> Type or Value or Category and it can keep changing
Part 3 -> It's a numeric value binding Part 1, Part 2 and Part 3 like Spreadsheet row.
The last key is always called
My_rowOrder and it's a comma delimeted value. It specifies how to construct the output array.
In the above example, 2,1 means a key value pair of
My_Type_2=Sony&My_Value_2=PS4&My_Category_2=Console should be the first in the output array.
Using JavaScript, I would like to parse the string and create an array out of it, such that the output is:
Array
(
[ 0 ] => Array
(
[Type] => Sony
[Value] => PS4
[Category] => Console
[Row] => 2
)
[ 1 ] => Array
(
[Type] => SSD
[Value] => 16GB
[Category] => Disk Capacity
[Row] => 1
)
)
How can I do this? I am partially able to do it this way:
function StringToArray(string) {
var request = {};
var pairs = string.split('&');
for (var i = 0; i < pairs.length-1; i++) {
var pair = pairs[i].split('=');
request[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
//I think I am in the right track, but need assistance
}
Your example output uses associative arrays, which JavaScript doesn't have, but you can use an array of objects instead.
This example outputs an array of objects, in the order specified by the rowOrder parameter. It trims the prefix (defined by prefix), and also trims the row number from the end of the key.
This will also work with the parameters in any order - e.g. you can mix them and it will parse as necessary, and the rowOrder parameter can appear anywhere in the string (doesn't have to be at the end).
Demo
function StringToArray(string) {
var prefix = 'My_'; // set the prefix
var output = [], request = [];
var pairs = string.split('&');
var order;
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
if (pair[0].replace(prefix, '') == 'rowOrder') {
order = pair[1];
} else {
var key = decodeURIComponent(pair[0]);
var pos = key.lastIndexOf('_');
var trimmedKey = key.substring(0, pos).replace(prefix, '');
var row = key.substring(pos + 1);
var value = decodeURIComponent(pair[1]);
var found = false;
for (var j = 0; j < output.length; j++) {
if (output[j].Row == row) {
output[j][trimmedKey] = value;
found = true;
}
}
if (!found) {
var obj = { 'Row': row };
obj[trimmedKey] = value;
output.push(obj);
}
}
}
// do the ordering based on the rowOrder parameter
var orderList = order.split(",");
for(var k=0; k<orderList.length; k++){
for(var l=0; l<output.length; l++){
if(output[l].Row == orderList[k]){
request.push(output[l]);
break;
}
}
}
return request;
}
Outputs an array of objects in the order specified by the My_rowOrder parameter:
[
{
Row: "2",
Type: "Sony",
Value: "PS4",
Category: "Console"
},
{
Row: "1",
Type: "SSD",
Value: "16GB",
Category: "Disk Capacity"
}
]
This may works for you...
<script>
var data = "My_Type_2=Sony&My_Value_2=PS4&My_Category_2=Console";
var array = new Array();
alert(JSON.stringify(URLToArray(data)));
function URLToArray(url) {
var request = {};
var pairs = url.substring(url.indexOf('?') + 1).split('&');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
request[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return request;
}
</script>
Try this:
function StringToArray(string) {
var request = [[],[]];
var pairs = string.split('&');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
request[pair[0].slice(-1)-1][decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
//console.log(request)
}