Convert javascript string to array - javascript

I have string like this
'10:00','13:00','12:00','15:00','08:00','12:00'
I need it in format like this
Array(3)
Array[0] ['10:00', '13:00']
Array[1] ['12:00', '15:00']
Array[2] ['08:00', '12:00']
I tried with split method but without success.

You could replace single quotes with double quotes, add brackes and parse it as JSON and get an array, which is the grouped by two elements.
var string = "'10:00','13:00','12:00','15:00','08:00','12:00'",
array = JSON
.parse('[' + string.replace(/'/g, '"') + ']')
.reduce((r, s, i) => r.concat([i % 2 ? r.pop().concat(s) : [s]]), []);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

var str = "'10:00','13:00','12:00','15:00','08:00','12:00'";
var oldArray = str.split(',');
var newArray = [];
while(oldArray.length){
let start = 0;
let end = 2;
newArray.push(oldArray.slice(start, end));
oldArray.splice(start, end);
}
console.log(newArray);

How about:
"'10:00','13:00','12:00','15:00','08:00','12:00'"
.replace(/'/g, '').replace(/(,[^,]*),/g,"$1;")
.split(';').map(itm => itm.split(','))

In this case you want to compare 2 values.
To do this you can make a for loop that reads the current value and the last value and compares the two.
If the last value is higher than current value, the splitting logic happens.
Either you add the current value to the last item (which is an array of strings) in the results array or you add a new array of strings at the end of the results array.

One potential solution:
let S = "'10:00','13:00','12:00','15:00','08:00','12:00'";
let R = S.split(',');
let I = 0;
let A = new Array([],[],[]);
R.map((object, index) => {
A[I][index % 2] = R[index];
if (index % 2 == 1) I++;
});
console.log(A);

You can use String.split(',') to split into individual values, then group them based on their positions (result of integer division with 2).
I am using groupBy from 30 seconds of code (disclaimer: I am one of the maintainers of the project/website) to group the elements based on the integer division with 2. Short explanation:
Use Array.map() to map the values of an array to a function or property name. Use Array.reduce() to create an object, where the keys are produced from the mapped results.
The result is an object, but can be easily converted into an array using Object.values() as shown below:
var data = "'10:00','13:00','12:00','15:00','08:00','12:00'";
const groupBy = (arr, fn) =>
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
acc[val] = (acc[val] || []).concat(arr[i]);
return acc;
}, {});
var arr = data.split(',');
arr = groupBy(arr, (v, i) => Math.floor(i / 2));
arr = Object.values(arr);
console.log(arr);
.as-console-wrapper { max-height: 100% !important; top: 0; }

I think use JSON.parse is better:
var array = "'10:00','13:00','12:00','15:00','08:00','12:00'";
array = JSON.parse( '[' + array.replace(/'/g,'"') + ']' );
var array2 = [];
for(var i=0;i < array.length - 1; i++){
array2.push([array[i], array[i+1]]);
}
console.log(array2);

Related

stopping a map or filter from iterating the last index

var arr = [1,2,3,4]
arr.map((x,i) => arr[i+1] - x)
// 1,1,1,NaN
Is there a way you can use the index in an Array.map or Array.filter method to compare value with-out comparing the final index to avoid the outcome of NaN?
You can use Array#slice to remove the last element before applying map.
var arr = [1,2,3,4]
console.log(arr.slice(0,-1).map((x,i) => arr[i+1] - x));
The shortest way you could do this would be
var mapped = arr.map((x,i) => arr[i+1] - x).filter(x => x);
Which is saying filter all the values where x is True
But I don't think you can do this with only map. I think map always returns an array of equal length.
You use reduce to achieve this though.
var arr = [1,2,3,4]
var reduced = arr.reduce((ids,x,i) => {
if (i < arr.length-1 ){
ids.push(arr[i+1] - x)
}
return ids
}, []);
console.log(reduced)
Outputs
[ 1, 1, 1 ]
Yes, you can. Just use Arra.filter() and return only the value that has a primitive value:
var arr = [1,2,3,4];
var newArr = arr.map((x,i) => arr[++i] - x)
.filter(val => val);
console.log(newArr);

Sort array by custom function in JavaScript

I am using only Javascript.
I have the following string :
?pn1=age&pn2=name&pv1=12&pv2=alice
What I need to do, is have the following outcome :
age:12|name:alice
I thought of a way to do this, it is the following :
var str = "?pn1=age&pn2=name&pv1=12&pv2=alice";
var strSplit = str.split("&");
for (var i = 0; i < strSplit.length; i++) {
console.log(strSplit[i]);
}
This returns the following result :
?pn1=age
pn2=name
pv1=12
pv2=alice
Since I want to join together pn1 and pv1 and pn2 and pv2, the number present in the end of the string is important.
?pn1=age
pn2=name
pv1=12
pv2=alice
So I thought a way to do this is to sort the array by this number. and then joining every 2 values together after sorting.
I tried the following code :
strSplit.sort(function() {
var pref = strSplit[i].split('=')[0];
return pref.charAt(pref.length-1);
});
It does not seem to work
Any help would be appreciated
You could split the parts, collect all items and return a joined string.
var string = '?pn1=age&pn2=name&pv1=12&pv2=alice',
result = string
.slice(1)
.split('&')
.reduce((r, p) => {
var [k, value] = p.split('='),
[key, index] = k.split(/(\d+)/);
index--;
r[index] = r[index] || {};
r[index][key] = value;
return r;
}, [])
.map(({ pn, pv }) => [pn, pv].join(':'))
.join('|');
console.log(result);
You can do that in following steps.
You can loop through half of the array and add corresponding keys and values to an array.
Consider i is the current index when we loop through half array.
The element at position i will be key.
Add the half of the length and add it to i to get corresponding value.
split() both key and value by = and get the second element.
var str = "?pn1=age&pn2=name&pv1=12&pv2=alice";
var arr = str.split("&");
let half = arr.length/2
let res = [];
for (var i = 0; i < half; i++) {
res.push(`${arr[i].split('=')[1]}:${arr[i + half].split('=')[1]}`);
}
console.log(res.join('|'))
You could use URLSearchParams to convert the query string to a collection of key-value pair.
Then loop through them to group the the pv and pn values based on the number.
Separate the string and and number values using the regex: (\D+)(\d+)
Loop through the obj.pn and get the corresponding pv value for the same number
Join the resulting array with |
This works with pn and pv values in any random order
const searchParams = new URLSearchParams("?pn1=age&pn2=name&pv1=12&pv2=alice")
const obj = { pn: {}, pv: {} }
for (let [key, value] of searchParams) {
const [, k, number] = key.match(/(\D+)(\d+)/)
obj[k][number] = value
}
const output = Object.entries(obj.pn)
.map(([n, key]) => `${key}:${obj.pv[n]}`)
.join("|")
console.log(output)
One idea is to first split values on & and add it to take digit as key and place on object and then later place the respective values in desired format
var str = "?pn1=age&pn2=name&pv1=12&pv2=alice".replace(/^\?/,'')
var strSplit = str.split("&");
let op = strSplit.reduce((op,inp) => {
let [key,value] = inp.split('=')
let digit = key.match(/\d+/)[0]
op[digit] = op[digit] || []
op[digit].push(value)
return op
},{})
let final = Object.values(op).reduce((op,inp) => {
let [key,value] = inp
op.push(`${key}:${value}`)
return op
} ,[]).join(' | ')
console.log(final)
You could convert that & split to a string and remove the ?xxx= then split it again by , to finally have an array with the stuff you're looking at.
var str = "?pn1=age&pn2=name&pv1=12&pv2=alice";
var split = str.split('&').toString().replace(/([?]?[pnv0-9]+[=])/g,'').split(',');
console.log(split[0] + ':' + split[2] + '|' + split[1] + ':' + split[3]);
EDIT : worth mentioning for those who are looking to the best performing solution, I tested all those provided here, click here for more infos.
The solution's list from the fastest to the slowest :
Maheer Ali (113,610 ops/s ±1.48% fastest)
tcj (112,324 ops/s ±1.01% 1.13% slower)
Nina Scholz (81,067 ops/s ±1.81% 28.64% slower)
Code Maniac (80,074 ops/s ±0.99% 29.52% slower)
adiga (33,065 ops/s ±0.92% 70.9% slower)

Sorting an Array of comma separated string using JavaScript

I came across with a weird requirement and I am struggling for last few hours to complete it. Below is my Array of string(just an example, the actual array contains around 2500 records):
var testArray = [
"130,839.9,855,837.3,848.65,3980489",
"129,875,875,828.1,833.25,6926078",
"138,891.3,893.3,865.2,868.75,5035618"
]
We have 3 element here of which each element is comma separated(each element have 6 item). i.e:
testArray[0] = "130,839.9,855,837.3,848.65,3980489"
My problem is, I wanted to sort testArray based on the first item of each element and convert it to array of array having all value into float, so the output would be:
[
[129, 875, 875, 828.1, 833.25, 6926078],
[130, 839.9, 855, 837.3, 848.65, 3980489],
[138, 891.3, 893.3, 865.2, 868.75, 5035618]
]
I am able to sort individual item but not the entire array as a whole, and I have tried using split and then sort with no luck.
Can someone help me out with this and please let me know if I am not clear.
Convert the array using Array#map within an Array#map, then use Array#sort on the converted array according to the [0] indices (a[0] - b[0]):
In ES5
var testArray = [
"130,839.9,855,837.3,848.65,3980489",
"129,875,875,828.1,833.25,6926078",
"138,891.3,893.3,865.2,868.75,5035618"
]
var converted = testArray.map(function (item) {
return item.split(',').map(function (num) {
return parseFloat(num);
});
})
console.log(converted)
var sorted = converted.sort(function (a, b) { return a[0] - b[0] })
console.log(sorted)
In ES6
const testArray = [
"130,839.9,855,837.3,848.65,3980489",
"129,875,875,828.1,833.25,6926078",
"138,891.3,893.3,865.2,868.75,5035618"
]
const converted = testArray.map(
item => item.split(',').map(
num => parseFloat(num)
)
)
console.log(converted)
const sorted = converted.sort((a, b) => a[0] - b[0])
console.log(sorted)
In ES6 (condensed)
const testArray = [
"130,839.9,855,837.3,848.65,3980489",
"129,875,875,828.1,833.25,6926078",
"138,891.3,893.3,865.2,868.75,5035618"
]
const convertedAndSorted = testArray
.map(n => n.split(',')
.map(num => parseFloat(num)))
.sort((a, b) => a[0] - b[0])
console.log(convertedAndSorted)
Just map the splitted and to number formatted values and sort by the first item.
var data = ["130,839.9,855,837.3,848.65,3980489", "129,875,875,828.1,833.25,6926078", "138,891.3,893.3,865.2,868.75,5035618"],
result = data
.map(s => s.split(',').map(Number))
.sort((a, b) => a[0] - b[0]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var testArray = ["130,839.9,855,837.3,848.65,3980489","129,875,875,828.1,833.25,6926078","138,891.3,893.3,865.2,868.75,5035618"];
const output = [];
for (let i = 0; i < testArray.length; i++) {
var numbers = testArray[i].split(',');
for (let j = 0; j < numbers.length; j++) {
numbers[j] = +numbers[j];
}
output[i] = numbers;
}
output.sort(function(x, y) {
return x[0] - y[0];
});
or shorter
output = testArray.map(s => s.split(',')).map(e => e.map(n => +n)).sort((x, y) => x[0] - y[0]);
First convert each of the Strings to an array of floats values using Array.map() and parseFloat().
After that you can simply sort the array of arrays using Arrays.sort()
Try the following :
var arr = ["130,839.9,855,837.3,848.65,3980489","129,875,875,828.1,833.25,6926078","138,891.3,893.3,865.2,868.75,5035618"];
var result = arr.map((a)=> a.split(",").map((b)=>parseFloat(b))).sort((a,b)=> a[0] -b[0]);
console.log(result);

Search string using RegEx for repeated letters and outputting into two-dimensional array in Javascript

I just started getting into RegEx. So far I have something like this but it looks like my pattern is off.
function hasRepeatedLetters(str) {
var patt = /[a-zA-Z]/g;
var result = patt.exec(str);
return result;
}
console.log(hasRepeatedLetters('aaBcDDbcca'));
I'd like to be able to input any argument with a combo of letters and the output to be a two-dimensional array with the first value being the repeated letter and the second value being the repeated letters length.
[["a",3],["b",1],["B",1],["c",3],["D",2]]
Here is a map / object based solution
var str = 'aaBcDDbcca';
var map = {}; // create a hash for keys and their counts
// loop over all characters and then add count
Array.from(str).forEach(function(character) {
map[character] = map[character] ? map[character] + 1 : 1;
});
// finally, convert map to a 2D array with 1st item as key and second item as count
var counts = Object.keys(map).map(function(key) {
return [key, map[key]];
})
console.log(counts);
You could use an ES6 Map for this, which has some nice features:
a map's set method returns the map again
the spread syntax applied on a map produces the desired array of pairs
function hasRepeatedLetters(str) {
return [...[...str].reduce( (acc, c) => acc.set(c, (acc.get(c) || 0) + 1), new Map )];
}
console.log(hasRepeatedLetters('aaBcDDbcca'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Possible solution, using Array#forEach function.
var str = 'aaBcDDbcca'.split(''), obj = {};
str.forEach(v => obj[v] ? obj[v]++ : obj[v] = 1);
var res = Object.keys(obj).map(v => [v, obj[v]]);
console.log(JSON.stringify(res));
Personally, I would suggest you to keep it as an object.
var str = 'aaBcDDbcca'.split(''), obj = {};
str.forEach(v => obj[v] ? obj[v]++ : obj[v] = 1);
console.log(JSON.stringify(obj));

sorting a string of numbers that each have a letter inside. making sure to keep the same position of duplicates as in the original array

I have a string of numbers. each number has a letter randomly placed inside of the number. I need to sort those numbers based on the letter inside of each number alphabetically. However if there are duplicates, I have to keep the order from the original string. for example: "c21 32b 43a 2c3" must be sorted to "43a 32b c21 2c3" then i need to strip the letters out.
here is what i have so far:
function cats(s) {
let arr = s.split(' ').sort(function (a,b) {
return a.match(/[a-z]/i)[0].localeCompare(b.match(/[a-z]/i)[0]);
});
console.log(arr)
for (i = 0; i < arr.length; i++) {
arr[i] = arr[i].replace(/\D/g,'');
}
console.log(arr)
}
cats('y381 6a684 9c94 5x346 c9541 31w1 440x16 x620 1b33 y4773 c3019');
I can't seem to get the duplicate letters to sort correctly. this is important because later on i need to perform math on these numbers and the order is important to get the correct solution.
You can keep an array of the split strings as a reference and use the index to sort by when the letters match
let refArr = s.split(' ');
let arr = refArr.slice().sort(function (a,b) {
let aLetter = a.match(/[a-z]/i)[0], bLetter=b.match(/[a-z]/i)[0];
if(aLetter === bLetter){
return refArr.indexOf(a) - refArr.indexOf(b);
}else{
return aLetter.localeCompare(bLetter);
}
});
You just require a small mod, basically do a map before the sort, to store the array index, the sort then can use the index to do a composite sort, and then we use map to put back into the format you had before.
function cats(s) {
let arr = s.split(' ').
map(function (v,i) { return {v:v, i:i }}).
sort(function (a,b) {
return a.v.match(/[a-z]/i)[0].localeCompare(b.v.match(/[a-z]/i)[0]) || a.i - b.i}).
map(function (v) { return v.v; });
console.log(arr)
for (i = 0; i < arr.length; i++) {
arr[i] = arr[i].replace(/\D/g,'');
}
console.log(arr)
}
cats('y381 6a684 9c94 5x346 c9541 31w1 440x16 x620 1b33 y4773 c3019');
You could use sorting with map and get a new array with the sorted items. This maintains the order of the items with same letters.
var array = 'y381 6a684 9c94 5x346 c9541 31w1 440x16 x620 1b33 y4773 c3019'.split(' ');
var mapped = array.map((el, i) => ({ index: i, letter: el.match(/[a-z]/i)[0] }));
// sorting the mapped array containing the reduced values
mapped.sort((a, b) => a.letter.localeCompare(b.letter) || a.index - b.index);
// container for the resulting order
var result = mapped.map(el => array[el.index]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories