I am looking for a JavaScript function which accepts two string arrays of equal length and outputs a single string array which is the same length as the input arrays, containing the element-wise-concatenated strings of the input arrays. Is there a built-in JavaScript function which does this?
Additionally, I would like to add in a string between the concatenated elements when the element-wise concatenation is done. For example, so that this would be true for each i:
outputArray[i] = inputArray1[i] + " - " + inputArray2[i]
You could reduce an array with the single arrays. This works for more than one array as well.
var inputArray1 = ['abc', 'def', 'ghi'],
inputArray2 = ['3', '6', '9'],
outputArray = [inputArray1, inputArray2].reduce((a, b) => a.map((v, i) => v + ' - ' + b[i]));
console.log(outputArray);
More functional
var inputArray1 = ['abc', 'def', 'ghi'],
inputArray2 = ['3', '6', '9'],
outputArray = [inputArray1, inputArray2]
.reduce((a, b) => a.map((v, i) => [].concat(v, b[i]))) // get single parts
.map(a => a.join(' - ')); // join inner arrays
console.log(outputArray);
Related
I'm trying to get the values from an array so I can filter them.
Using hints from
Add single quotes in a string array javascript but it doesn't return the whole array with quotes around each value.
Tried:
var ages = Array.from({ length: 5 }, (_x, i) => i + 1);
console.log(ages); // [1,2,3,4,5]
ages = ages.toString();
console.log(ages); // "1,2,3,4,5"
const newArr = ages[0].split(",").map(x => x.trim());
console.log(newArr); // ["1"]
//desired: ["1","2","3","4","5",] or ["1","2","3","4","5"]
You are over-complicating this, particularly by first converting the entire array with toString(). It's as simple as follows:
const ages = Array.from({ length: 5 }, (_x, i) => i + 1);
const newArr = ages.map(age => age.toString());
console.log(newArr); // [ '1', '2', '3', '4', '5' ]
I have tried several methods and am not understanding why I cant simple get the sum of the numbers in my array. I.E.
Logger.log(shirtColor)
Logger.log(shirtColor.reduce((a, b) => a + b, 0))
Logger shows:
Info [0.0, 1, 2, 1]
Info 0121
Looks like shirtColor array contains string elements. That's the reason it is appending as a string.
If shirtColor is an array of string elements.
const arr = ['1', '2', '1'];
const res = arr.reduce((a, b) => a + b, 0);
console.log(res); // 0121
If shirtColor contains numeric elements.
const arr = [0.0, 1, 2, 1];
const res = arr.reduce((a, b) => +a + +b, 0);
console.log(res); // 4
To achieve the requirement, You can convert a string to a number in JavaScript using the unary plus operator (+).
const arr = ['0.0', '1', '2', '1'];
const res = arr.reduce((a, b) => +a + +b, 0);
console.log(res);
I was able to use the comments to understand my oversight. I was pushing data that was a string. Instead the data I was pushing I added Number()
if (vs[i][15] > 0) {
shirtColor.push(Number(vs[i][15]))}
I have a array1 from checkboxes selected, and i need to compare with the most similar, how i do that?
var array1 = ["pain", "fever", "vomit"]
var array2 = ["diarrhea", "fever", "vomit", "embolism", "bleeding"]
var array3 = ["diarrhea", "tumor", "vomit", "cold", "bleeding"]
I tried some methods but they only return me as "true" or "false", I would like to get the most similar array1
You could count the number of similar elements using reduce, then order your arrays by similarity and take the first element:
const array1 = ["pain", "fever", "vomit"];
const array2 = ["diarrhea", "fever", "vomit", "embolism", "bleeding"];
const array3 = ["diarrhea", "tumor", "vomit", "cold", "bleeding"];
const countSimilarElements = (arr1, arr2) => arr1.reduce((count, x) => count + arr2.includes(x), 0);
const orderBySimilarity = (arr1, ...arr) =>
arr.map(x => ({ array: x, similarity: countSimilarElements(arr1, x) }))
.sort((a, b) => b.similarity - a.similarity);
const ordered = orderBySimilarity(array1, array2, array3);
console.log(ordered);
console.log(ordered[0].array);
This function takes in a the array you want to compare as the 'base' and a list of other arrays as 'arr_list', then returns a similarity array showing how similar each array in 'arr_list' was to the 'base'. This way you can compare multiple arrays with a single call and know reference their similarity by referencing the index of the returned similarity array.
const a = ['11', '22', '33'], b = ['11', '44', '55', '66'], c = ['55', '33', '11', '22'], d = ['11', '66', '44', '22'];
const Similarity = (base, arr_list) => {
let similarity = new Array(arr_list.length).fill(0);//creates similarity array which defaults to 0
base.forEach( el => {
arr_list.forEach( (arr, i) => similarity[i] += arr.includes(el) )
});
return similarity;
}
const similarity = Similarity(a, [b,c,d])
console.log(similarity)
i would like to split an array into multiple chunks but applying a function to it to decide how to create the chunks.
For example, if i have an array of letters, numbers or letters and numbers, apply a function to the array to split it into array of arrays of the previous categories.
let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']
myChunkFunction(arr, myCustomSplitFunction)
// result
[['a','b','c'], ['1','2','3'], ['a1', 'a2','a3']]
Lodash has a chunk function but it splits into n chunks, also array has a slice function but you need to specify the begin and the end so how could i split with a custom function.
Try doing this
let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']
const splitFn = (str) => Number.isInteger(+str) ? 0 : str.length == 1 ? 1 : 2
const myChunkFunction = (arr, fn) => arr.reduce((r,c) => {
let t = fn(c)
r[t] = [...r[t], c]
return r
}, [[],[],[]])
console.log(myChunkFunction(arr, splitFn))
Hint
The key to the answer is to, somehow, reorganize the source array such that all the elements with the same key will be in the same place.
The easiest way I can think to solve it is by using hash-map. Each element in the hash-map will be a different array containing all the elements with the same key.
Try it for your self before you keep reading and see the full solution.
The implementation
As you can see, I solved it as functional as possible. To avoid mutations, I used reduce to iterate over the source array and put each element in the hashmap (by generating a key from the element).
I recreate the final hash-map over and over using shallow copy. Finally, I convert the hash-map to an array of array (because that was your demand) using Object.values
const splitArrayByKey = extractKey => array => {
const arraysByKey_obj = array.reduce((hashMapOfArrays,element)=> {
const key = extractKey(element);
// if we already added an element with the same key,
// then we add the current element to there.
// else, we create a new key and put the current element there.
if(hashMapOfArrays.hasOwnProperty(key))
return {
...hashMapOfArrays,
[key]: [...hashMapOfArrays[key],element]
};
return {
...hashMapOfArrays,
[key]: [element]
};
},{});
// transform the arraysByKey_obj to an array of arrays:
return Object.values(arraysByKey_obj);
};
// example 1:
const result1 = splitArrayByKey(element=>element)([1,2,3,1,2,3]);
console.log(result1);
console.log('------------------');
// example 2:
const result2 = splitArrayByKey(element=>element.id)([{id:1,x:1},{id:{},x:2},{id:"id",x:3},{id:1,x:4}]);
console.log(result2);
Here is a way to do this via ES6:
let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']
const splitFn = (str) => Number.isInteger(+str) ? 0 : str.length == 1 ? 1 : 2
const myChunkFunction = (arr, fn) => arr.reduce((r,c) => {
let t = fn(c)
r[t] = [...r[t], c]
return r
}, [[],[],[]])
console.log(myChunkFunction(arr, splitFn))
The typeFn plays the role of filtering the elements to number, string with 1 length and other. That output is used by the myChunkFunction to place the element in the right array.
You could do something like this with less control and in one line with reduce and ES6 array spread:
let arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3']
const result = arr.reduce((r,c) =>
(Number.isInteger(+c) ? r[0] = [...r[0], c] :
c.length == 1 ? r[1] = [...r[1], c] : r[2] = [...r[2], c], r), [[],[],[]])
console.log(result)
You start with [[],[],[]] and fill each of the sub arrays based on number, length of the string == 1, other lenghts.
You could wrap that in a function.
const arr = ['a', 'b', '1', '2', 'a1', 'a2', 'c', '3', 'a3'];
const getClassification = function(x){
const hasNumber = x.split('').some(x => parseFloat(x));
const hasChar = x.split('').some(x => !parseFloat(x));
if(!parseFloat(x) && (!hasNumber && hasChar)) return 0;
else if(parseFloat(x)) return 1;
else return 2;
}
const myChunkFunction = function(arr, classifier){
let jaggedArray = [[], [], []];
arr.forEach(x => {
jaggedArray[classifier(x)].push(x);
})
return jaggedArray;
}
console.log(myChunkFunction(arr, getClassification));
I think this satisfies.
I have a little question about joining arrays. I have an array of letters, something like that:
let array = ['a','b','','c']
I wan't to join elements in array to have output like that:
let array = ['ab','c']
Can you help me? I was searching but everything i found was about removing whitespaces from arrays or string :(
Something along these lines:
let array = ['a', 'b', '', 'c'];
let res = array.reduce((res, s) => {
if (s.length) {
res[res.length - 1] += s;
} else {
res.push('');
}
return res;
}, ['']);
console.log(res);
It does make the assumption that there will be at least one string in the array, that the last element won't be an empty string and that there won't be two adjacent empty strings. Adjust as necessary if those are concerns.
You can use a combination of Array#map, Array#join and String#Split to achieve what you want.
Here, I used a space as the delimiter, but you can use anything that you don't use in your array.
let array = ['a','b','','c'];
let result = array.map(e => e.length ? e : ' ').join('').split(' ');
console.log(result);
You could use reduce() method to create new array and one variable to increment on empty string.
let array = ['a', 'b', '', 'c', 'd', 'e', '', '', '', 'f', '', 'g'];
let i = 0;
let result = array.reduce((r, e, j, arr) => {
r[i] = (r[i] || '') + e;
if (!e && arr[j - 1]) i++
return r;
}, [])
console.log(result)