Parsing JavaScript string into 2 arrays - javascript

You have a string that is in a following format: "Applejack=A.J.+Applecar,Lemon+Vodka=AlfieCocktail+ Sunset + SexOnTheBeach" and etc.
In Javascript (use .split()), write code to parse a string like this(can be 100000 characters long) that puts the input in 2 different arrays(array key, array values) such that the arrays would llok like the following:
key = ["Applejack", "Lemon+Vodka"]
values = ["A.J+Applecar","AlfieCocktail+Sunset+SexOnTheBeach"]

key = string.split(',').map(x=>x.split("=")[0])
values = string.split(',').map(x=>x.split("=")[1])

You could do something like this
var str = "Applejack=A.J.+Applecar,Lemon+Vodka=AlfieCocktail+ Sunset + SexOnTheBeach";
var first = str.split(',');
var keys = [];
var values = [];
for(let i = 0; i < first.length; i++){
let in_two = first[i].split('=');
keys.push(in_two[0]);
values.push(in_two[1]);
}
console.log(keys);
console.log(values);

You can do it like this:
let str = "Applejack=A.J.+Applecar,Lemon+Vodka=AlfieCocktail+ Sunset + SexOnTheBeach";
let allValues = str.split(','), keys = [], values = [];
allValues.forEach(value => {
const [k,v] = value.split('=');
keys.push(k);
values.push(v);
})
console.log(keys,values);

You can simply use map with reduce.
const str =
"Applejack=A.J.+Applecar,Lemon+Vodka=AlfieCocktail+ Sunset + SexOnTheBeach";
const [keys, values] = str
.split(",")
.map((item) => item.split("="))
.reduce(
(acc, item) => [acc[0].concat(item[0]), acc[1].concat(item[1])],
[[], []]
);
console.log(keys, values);

Related

Get Key Value pair after String Split

I have a string in the form
Key=asdf, num=90, Key=ert, num=20, Key=yged, num=20, Key=kned, num=35
I have to filter only Key num pairs which has value 20 and store them into a Key Value pair such that Key=ert, num=20 will be first record and Key=yged, num=20 will be second record so on. How can I use Map in JavaScript so that always first value will go as key and second will go as value and form pairs in this case. I have used the following :
var dataString = JSON.parse(data).data;
var arrayVal = new Array();
arrayVal = dataString.split(', ');
for(a in arrayVal){
console.log(arrayVal[a]);
}
Array.map probably isn't the best tool for the job here. Array.reduce would be a better approach. Since you know what your delimiters are (namespaces and equal signs), you can logically split things up so that you know that every other iteration will give you a key/value. You can then create a mechanism to track what the last key is so you can map the value to it.
const str = 'Key=asdf, num=90, Key=ert, num=20, Key=yged, num=20, Key=kned, num=35';
const arr = str.split(', ').reduce( (acc, curr) => {
const entry = curr.split('=');
const key = entry[0];
const val = entry[1];
if (key === 'Key') {
acc['last_key'] = val
acc[val] = null;
} else if (key === 'num') {
acc[acc['last_key']] = val;
}
return acc;
}, {});
delete arr.last_key;
console.log(arr);
Here you go. It's kinda ugly.
let result = dataString.split(', ')
.map((value, index, array) =>
value === 'num=20' && array[index - 1])
.filter(x => x);
console.log(result);
Here's my say
const dataString = JSON.parse(data).data;
const arrayVal = dataString.split(', ');
const obj = {}; // initialize the object
for (let i = 0; i < arrayVal.length; i += 2) { // Iterating over two elements for the key and value
const key = arrayVal[i].split('=')[1];
const value = arrayVal[i + 1].split('=')[1];
obj[key] = value;
}
console.log(obj);

Is there an ES6 method to search an array for elements with elements from another array?

I have two arrays containing some parameter values. All elements in the arrays are strings like the following:
x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"]
y = ["nenndrehzahl=500,3000"]
Expected Output would be:
x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=500,3000"]
I have tried using Array.Filter but can't seem to be able to filter only partially (like starting with the string instead of the whole string since that won't match as the values are different).
What I'd like is to be able to go through each element from array Y, and search if the element(string before "=") exists in array X and replace the value(s) of that element in array X.
for(var i=0;i<x.length;i++){
var currentStr = x[i];
var currentInterestedPart = /(.+)=(.+)/.exec(currentStr)[1];
var replacePart = /(.+)=(.+)/.exec(currentStr)[2];
for(var j=0;j<y.length;j++){
if(!y[j].startsWith(currentInterestedPart)) {continue;}
var innerReplacePart = /(.+)=(.+)/.exec(y[j])[2];
x[i] = currentStr.replace(replacePart,innerReplacePart);break;
}
}
Try this. This makes use of RegEx and it is less error prone.
You can use Map and map
First create a Map from array y, split each element by = use first part as key and second part as value
Loop over x array, split each element by = and use first part as key to search in Map if it's present use value from Map else return without any change
let x = ["vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"]
let y = ["nenndrehzahl=500,3000"]
let maper = new Map(y.map(v => {
let [key, value] = v.split('=', 2)
return [key, value]
}))
let final = x.map(v => {
let [key, value] = v.split('=', 2)
if (maper.has(key)) {
return key + '=' + maper.get(key)
}
return v
})
console.log(final)
For each value in the y array, iterate and check if the word exist in the x array. Once you find a match just update the value. (The below solution mutates the original array)
const x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"],
y = ["nenndrehzahl=500,3000"],
result = y.forEach(word => {
let [str, number] = word.split('=');
x.forEach((wrd,i) => {
if(wrd.split('=')[0].includes(str)) {
x[i] = word;
}
});
});
console.log(x);
I'd suggest using combination of reduce + find - this would accumulate and give you the results you're expecting.
var x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"]
var y = ["nenndrehzahl=500,3000"]
var combinedArr = x.reduce((acc, elem, index) => {
const elemFoundInY = y.find((yElem) => yElem.split("=")[0] === elem.split("=")[0]);
if (elemFoundInY) {
acc = [...acc, ...[elemFoundInY]]
} else {
acc = [...acc, ...[elem]];
}
return acc;
}, [])
console.log(combinedArr);
You can use .startsWith() to check if element start with key= and then replace its value:
let x = [ "vorzugsreihe=J", "nennleistung=94,1127", "nenndrehzahl=31,9400"];
let y = ["nenndrehzahl=500,3000"];
y.forEach(val => {
let [key, value] = val.split("=");
for (let i = 0; i < x.length; i++) {
if (x[i].startsWith(`${key}=`)) x[i] = `${x[i].split("=")[0]}=${value}`;
}
})
console.log(x)
Try this:
y.forEach(item => {
const str = item.split("=")[0];
const index = x.findIndex(el => el.startsWith(str));
if (index) {
const split = x[index].split('=');
x[index] = `${split[0]}=${split[1]}`;
}
})

Convert string into key-value pairs in an array

I have a string:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
I want to convert this string to key-> value pairs in an array.
[
dtstart: 20190514T111500Z,
freq: daily,
interval: 1
]
I know I can take the string and split it based on the semicolon:
var array = rrule.split(";");
... but this leaves me with an array like this:
[
"DTSTART=20190514T111500Z",
"FREQ=DAILY",
"INTERVAL=1"
]
I guess I need another step to map out the keys/values, but I get lost at this point.
Ideally, for the string I want to be able to easily access what dtstarts equals, what interval equals, what other variables equal and so on.
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let obj = {};
for (let entry of str.split(";")) {
let pair = entry.split("=");
obj[pair[0]] = pair[1];
}
console.log(obj);
You already know how to split on the ; to get an array, from there you can just aggregate (using reduce) to get an object:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
var result = rrule.split(";").reduce( (obj,item) => {
let [key,value] = item.split("=");
obj[key] = value;
return obj;
},{});
console.log(result["DTSTART"])
console.log(result["FREQ"])
console.log(result["INTERVAL"])
You were correct to start with split first, this would then return you an array of strings.
To easily convert them, just use map, to return the split the single strings once more, and then return an object based on the property name you would like to give it and it's value
function createKeyValuePairFromString( str ) {
return str.split(';').map( item => {
const splitted = item.split('=');
return { [splitted[0]]: splitted[1] };
});
}
console.log( createKeyValuePairFromString("DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1") );
Use array created and split it again with =
function convertToObject(cookieString) {
const cookieObj = {};
if (!cookieString && typeof cookieString !== 'string') return cookieObj;
const arr = cookieString.split(';');
arr.forEach(record => {
if (record.includes('=')) {
const [key, value] = record.split('=');
cookieObj[key.trim()] = value;
}
});
return cookieObj;
}
You can use it like the code below:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let finalObj = {};
rrule.split(';').forEach(i => finalObj[i.split('=')[0]] = i.split('=')[1]);
console.log('finalObj',finalObj);
Here I'm first splitting with ';' so consider the first item to be DTSTART=20190514T111500Z Then on splitting with = I get finalObject['DTSTART'] = 20190514T111500Z
Using forEach()
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let obj = {};
let strArr = str.split(';')
strArr.forEach((str) => {
let [key, value] = str.split('=')
obj[key] = value;
});
console.log(obj);
Here's a fairly simple version, returning an object, not an array:
const toObj = str => str
.split (';')
.map ( s => s .split ('=') )
.reduce ( (a, [k, v]) => ({...a, [k]: v}), {} )
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
console.log (
toObj(str)
)
One of the reasons I like the library is that we can write this sort of logic more simply. In Ramda (disclaimer: I'm one of the authors), it might look like this:
const toObj = pipe ( split (';'), map (split ('=') ), fromPairs)
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
console.log (
toObj(str)
)
<script src="https://bundle.run/ramda#0.26.1"></script><script>
const {pipe, split, map, fromPairs} = ramda; </script>
var str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
// string splitting rule
const rule = (string, delimiter) => string.split(delimiter);
const result = rule(str, ';').reduce((acc, s) => {
const [key, value] = rule(s, '=');
acc[key] = value;
return acc;
}, {});
console.log(result);

Find common words and push into new array

I have Array below and attached output.
`var
arrayData=['cat','mat','tac','hiller','mamaer','llerih','eramam'];
output : [[cat,tac], [mat], [hiller,llerih], [mamaer,erama]];`
Want to extract common letter in an array and store in new array.
i was trying to implement using array.reducer.
You can do this with Map and a simple loop. The idea is you record each word by creating a "key" from the sum of their character code and length of the word.
Used Array#Reduce to sum the words character codes.
i.e.:
//sum of each letter's character code using reduce
const res1 = "test".split("").reduce((a,c)=>a+c.charCodeAt(), 0);
const res2 = "ttes".split("").reduce((a,c)=>a+c.charCodeAt(), 0);
const l = "test".length;
const key1 = `${l}_${res1}`;
const key2 = `${l}_${res2}`;
console.log(key1, key2, key1 === key2); //4_448 4_448 true
i.e. (without reduce and with for loop):
function sum(word){
let s = 0;
for(let i = 0; i < word.length; i++){
s += word[i].charCodeAt();
}
return s
}
//sum of each letter's character code using reduce
const res1 = sum("test");
const res2 = sum("ttes");
const l = "test".length;
const key1 = `${l}_${res1}`;
const key2 = `${l}_${res2}`;
console.log(key1, key2, key1 === key2); //4_448 4_448 true
Recording the length of the word adds an extra level of security incase two different words of lengths different had the same sum
Full Solution:
const data = ['cat','mat','tac','hiller','mamaer','llerih','eramam'];
const m = new Map();
for(let i = 0; i < data.length; i++){
const word = data[i];
const sum = word.split("").reduce((a,c)=>a+c.charCodeAt(), 0);
const key = `${word.length}_${sum}`;
m.set(key, [word].concat(m.get(key)||[]));
}
const res = Array.from(m.values());
console.log(res);
I solved it with a different way, I sorted them, grouped them then displayed them by index.
var arrayData=['cat','mat','tac','hiller','mamaer','llerih','eramam'];
var sortedArrayData = arrayData.map(itm => itm.split('').sort((a,b) => a>b).join(''));
var data = {};
sortedArrayData.forEach((itm, indx) => {
if(!data[itm]) data[itm] = [];
data[itm].push(indx)
});
var result = Object.keys(data).map(key => {
return data[key].map(it => arrayData[it])
})
console.log(result)
try it here

Return only numbers in an array

I have a database in Firebase, which I then convert to an array, this is my code:
let timeRef = firebase.database().ref('root/grupo0/user0/0');
function snapshotToArray(snapshot) {
let returnArr = [];
snapshot.forEach(function(childSnapshot) {
let item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
};
const timeRefArray = timeRef.on('value', function(snapshot) {
console.log(snapshotToArray(snapshot));
});
Each element is like this: ^MED~#1550648873
How can I return each element only with numbers?
I think you want just only the number included in the item string. Then, you need a regex to get the number. In your code, replace the line returnArr.push(item); with:
var m = /\d+/.exec(item);
if (m) {
returnArr.push(m[0] * 1);
}
The *1 is to cast the number to integer.
You can use string.match() with a regex to extract the digit, then convert the result to a number with parseInt. You can then conditionaly push the item to the array if it is not NaN:
const items = ['^MED~#1550648873', '^MED~#'];
const returnArr = [];
items.forEach(item => {
const value = parseInt((item.match(/\d+/) || [''])[0]);
!isNaN(value) && returnArr.push(value);
});
console.log(returnArr);
Try This:
var arr = [ '^MED~#1550648873','Am2mm55','^MED' ] ;
var patt = new RegExp('\\d+','g') ;
var result = arr.reduce( (acc, ele) => {
if ( isTrue = ele.match(patt) ) { acc.push( isTrue.join('') ) ; }
return acc ;
}, []) ;
console.log( result ) ;
when returning each element to array you can use replace method:
str = item.replace(/\D/g,'');
returnArr.push(str);
then you can cut the non numeric part, before push it to your array.

Categories