I have a mixed array of values all string values. I want to take the string values representing a number and convert them to ints. Here is my array:
const data = 'new york;10.99;2000';
I split it transforming it:
const transData = data.split(';');
transData = ["new york", "10.99", "2000"]
I would like to iterate over that and return two clean int's with a string value for all non number strings. I am a bit stumped. I know this is easy to some but I have tried forEach, for, map, and I still get a NaN value for the first array member. I can't seem to filter or skip it even with an "if" check using for instance:
for(let i=0; i < transData.length; i++)
if(transData[i] != NaN){
transData[i] = + transData[i];
}else{continue};
I know how this works transData[i] = + transData[i];
I just can't seem to automate this thing with iteration/filter/map/whatever..
Any help greatly appreciated. These are baby steps into big boy/girl thinking in javascript.
Here are some of the methods I have tried:
const data = 'new york;10.99;2000';
const transData = data.split(';');
// transData[1] = + transData[1];
// transData[2] = + transData[2];
console.log(transData);
const filteredTransData = transData.filter(data => data > 0);
filteredTransData.forEach((data, idx) => {
filteredTransData[idx] = + filteredTransData[idx];
You can simply use || operater with .map() to get the desired output. As NaN is a falsey value so it would return the string under consideration as it is if it can't be converted to a number by Number:
const data = 'new york;10.99;2000';
const result = data.split(";").map(s => Number(s) || s);
console.log(result);
As pointed by #Maheer Ali:
Above solution has a limitation. It won't convert String "0" to Number 0 as 0 is a falsey value.
So we may use some other solution posted or we may explicitly apply a check for zero (0) where this modified array is being used.
NaN === NaN will always return false. To check if element is NaN you need to use isNaN function.
const transData = ["new york", "10.99", "2000"];
for(let i = 0; i< transData.length; i++){
if(!isNaN(transData[i])){
transData[i] = +transData[i];
}
}
console.log(transData)
Whenever you need to get a new value for each element of array based on previous value its better to use map()
const transData = ["new york", "10.99", "2000"];
const res = transData.map(x => isNaN(x) ? x : +x);
console.log(res)
Try something like this using MAP function
data.split(';').map((x)=>{
x= !isNaN(x)? parseFloat(x):x;
return x;
})
Yes, Maheer Ali's method is good. I just modified all code)
const data = 'new york;10.99;2000;0;-1;-2.45';
let transData = Array
.from(data.split(';'), x => parseFloat(x))
.filter( value => !Number.isNaN(value) );
console.log(transData);
Array.from() - creates a number array from the string array.
Array.filter() - removes NaN from the number array
Related
I have this array that has length = 3:
state = ["q0", "q1", "q2,q3"]
And I want to modify that, and I want it to look something like this:
state = ["q0", "q1", "q2", "q3"] // length = 4.
I want to cut the string = "q2,q3" in a way that I will get "q2" and "q3" so that I can replace the state[2] value with "q2" and automatically add to the array like state[3] = "q3".
Does anyone know how can I do it?
I tried the split method but it didn't work as I wanted.
flatMap is perfect for this.
["q0", "q1", "q2,q3"].flatMap(v => v.split(','))
flatMap maps and then flattens. So mapping using split gives you [['q0'], ['q1'], ['q2', 'q3']], then flattening unwraps each second-level array.
I would iterate over state, try to split each value and then push them to res array.
const state = ["q0", "q1", "q2,q3"];
const res = [];
state.forEach((value) => {
const splitValue = value.split(",");
res.push(...splitValue);
});
let state = ["q0", "q1", "q2,q3"];
state=state.join(',');
state=state.split(',');
console.log(state);
Hello I gave an example with gets the gap in the last index and splits it
let deneme = ["first","second","third fourth"];
let index = deneme[2].indexOf(" "); // Gets the first index where a space occours
let firstPart = deneme[2].slice(0, index); // Gets the first part
let secondPart = deneme[2].slice(index + 1);
console.log("first try" ,deneme);
deneme[2] = firstPart;
deneme.push(secondPart);
console.log("second look",deneme);
You can do it using three javascript methods. forEach(), concat(), and split(). One liner
let result = []
state.forEach(a => result = result.concat(a.split(",")))
One simple, and frankly naive, means of achieving this:
// initial state, chained immediately to
// Array.prototype.map() to create a new Array
// based on the initial state (["q0", "q1", "q2, q3"]):
let state = ["q0", "q1", "q2, q3"].map(
// str is a reference to the current String of the Array
// (the variable name is free to be changed to anything
// of your preference):
(str) => {
// here we create a new Array using String.prototype.split(','),
// which splits the string on each ',' character:
let subunits = str.split(',');
// if subunits exists, and has a length greater than 1,
// we return a new Array which is formed by calling
// Array.prototype.map() - again - and iterating over
// each Array-element to remove leading/trailing white-
// space with String.prototype.trim(); otherwise
// if the str is either not an Array, or the length is
// not greater than 1, we return str:
return subunits && subunits.length > 1 ? subunits.map((el) => el.trim()) : str;
// we then call Array.prototype.map():
}).flat();
// and log the output:
console.log(state);
References:
Array.prototype.flat().
Array.prototype.map().
Conditional ("ternary") operator.
`String.prototype.split().
String.prototype.trim().
Per #TrevorDixon's solution, Array#flatMap is the way to go. In case you have multiple separators you can use a regular expression with String#split as in the following demo:
const
input = ["q0", "q1", "q2,q3","q4 q5| q6"],
output = input.flatMap(v => v.split(/[ ,|]+/));
console.log( output );
Here is a working example of what I want to do:
let value = " Have you ever * looked* sam [5, 6]";
// let value = " Have you ever * looked* sam"; // we may have this instead
// So far I need to check if there is []
if(value.includes('[')){
const archiveGuidePure = value.substring(value.indexOf('['), value.length);
value = value.replace(archiveGuidePure, "");
const archiveGuide = JSON.parse(archiveGuidePure);
console.log(archiveGuide);
}
console.log(value);
As you see we have a string in value and the string might have an array prototype at the very end of it. note that sometimes we want that array and sometimes we don't.
The code checks the value to see if there is an array.
if there is an array it removes the array and returns it as an array. if there is not an array at the end of value then nothing changes.
So far I need to check if there is a [ sign otherwise I get an error which made my code ugly and in my mind a bad practice.
How do you do this without if statement?
Use regex and replace and no need to check
let value = " Have you ever * looked* sam [5, 6]";
const newValue = value.replace(/\[.+\]/, '');
// if there is no array in the string then it will be null or you can give it a default value
const array = JSON.parse(value.match(/\[.+\]/)) || [];
console.log(newValue);
console.log(array);
Update:
if you implement JSON.parse() more correctly you need to send string parameter
let value = " Have you ever * looked* sam [5, 6]";
const newValue = value.replace(/\[.+\]/, '');
const stringify = value.match(/\[.+\]/);
// if there is no array in the string then it will be null and you can give it a default value
const array = stringify
? JSON.parse(stringify[0])
: [];
console.log(newValue);
console.log(array);
let value = " Have you ever * looked* sam [5, 6]";
const query = /(\[.+\])/gi
const found = value.match(query);
if (found) {
const result = JSON.parse(found[0])
console.log(result)
}
You do no need to check if a '[' exists. The method replace will find it.
const p = 'Have you ever * looked* sam [5, 6]';
var newValue = p.replace( p.substring(p.indexOf('['), p.indexOf(']')+1), '');
var array = JSON.parse( p.substring(p.indexOf('['), p.indexOf(']')+1));
console.log(newValue)
console.log(array)
You replace the array, from when it is opened (p.indexOf('[')), until it is closed (p.indexOf(']')+1)
I have an object (key value pair) looks like this
I want to get a string of '[100000025]/[100000013]'
I can't use var str = OBJ[0].PC + OBJ[1].PC (which gives me '100000025100000013')
because I need the bracket structure.
The number of items can vary.
Added >> Can it be done without using arrow function?
const string = array.map(({PC}) => `[${PC}]`).join('/')
You could map every string to the string wrapped in brackets, then join that by slashes.
You can use a map() and a join() to get that structure. - this is hte same solution as Puwka's = but without the template literal.
var data = [
{am: 1, ct: "", pc: "1000000025"},
{am: 2, ct: "", pc: "1000000013"}
];
let newArr = data.map(item => "[" + item.pc +"]");
console.log(newArr.join("/")); // gives [1000000025]/[1000000013]
You can always use classic for in loop
let arr = [{PC:'1000'},{PC:'10000'}]
let arrOut = [];
for(let i = 0; i < arr.length; i++) {
arrOut.push('[' + arr[i].PC + ']');
}
now the arrOut is equal ["[1000]", "[10000]"] what we need is to convert it to a string and add '/' between items.
let str = arrOut.join('/');
console.log(str) // "[1000]/[10000]"
So you need a string in the format of: xxxx/yyyyy from a complex object array.
const basedata = [...];
const result = basedata.map( item => `[${item.PC}]` ).join('/')
so i will explain it now. The map function will return a new array with 1 entry per item. I state that I want PC, but i added some flavor using ticks to inject it inbetween some brackets. At this point it looks like: ["[1000000025]","[100000013]"] and then join will join the arrays on a slash, so it will turn into an array.
"[100000025]/[100000013]"
Now, this will expand based on the items in your basedata. So if you have 3 items in your basedata array, it would return:
"[10000000025]/[100000013]/[10000888]"
First if you want to divide the result then it will be better to change it into number and then just do the division.
Example
Number.parseInt("100000025")/Number.parseInt("100000013")
If you want to display it then better to use string interpolation
surround it with back tick
[${[0].PC}]/[${[1].PC}]
Hope this is what are you looking for
I am trying to filter some data from an array in a JSON file, based on an input of the form string1, string1,string2, string1,string2,string3 etc., that is, some strings separated by a ,.
What I'm trying to do:
let arrInput = document.getElementById('inputBox').val.split(',');
for(let i = 0; i < arrToFilter.length; i++){
if(.........what to write here?...........){
arrOutput.push(arrToFilter[i]);
}
}
return arrOutput;
If the arrInput had a fixed length, I could accomplish this using indexOf != -1 for each element in arrInput, but here, since the length of arrInput is variable, how can I check if at least one of the strings present in arrInput is also present as a substring in arrToFIlter[i]?
Edit:
Example:
Let arrToFilter be ["abcqwer", "pizza", "definition", "abcdef", "example"]
Case 1 :
Say the input entered (in an <input> element) is abc,def.
For this, the arrOutput should be ["abcqwer", "definition", "abcdef"]
Case 2:
Say the input entered is abc
Expected output : ["abcqwer", "abcdef"]
Simple way is using some and filter,
var string = 'ad,kk,sb';
var array = ['adik', 'klop', 'pp'];
var stringers = string.split(',');
var result = array.filter((arr) => {
var isPresent = stringers.some(stringer => arr.includes(stringer));
return isPresent ? true : false;
});
console.log(result);
You need to iterate both arrays
let arrToFilter = ['abcqwer', 'pizza', 'definition', 'abcdef', 'example'];
let arrOutput = [];
let arrInput = document.getElementById('inputBox').value.split(',');
arrToFilter.forEach(filter => {
arrInput.forEach(input => {
if (!!input && filter.includes(input)) {
arrOutput.push(filter);
}
});
});
// distinct the output
return arrOutput.filter((v, i, a) => i === a.indexOf(v));
I have a text file in which I have data on every line. It looks like this:
number0;text0
number1;text1
number2;text2
..and so on
So I loaded that text file into a variable via xmlhttprequest and then I converted it into an array using split by "\n" so now the result of lineArray[0] is number0;text0.. And now what I need is to split that array again so I could use number0 and text0 separately.
My idea being that I want to get the text0 by searching number0 for example lineArray[i][1] gives me texti..
Any ideas how to proceed now?
Thanks
You need to do an additional split on ; as split(';') so that lineArray[0][1], lineArray[1][1] and so on gives you text0, text1 and so on.
var str = `number0;text0
number1;text1
number2;text2`;
var lineArray = str.split('\n').map(function(item){
return item.split(';');
});
console.log(lineArray);
console.log(lineArray[0][1]);
console.log(lineArray[1][1]);
Knowing I'm late, still making a contribution.
As everyone else said, split it again.
let text = "number0;text0\nnumber1;text1\nnumber2;text2"
let data = text.split('\n');
var objects = {};
for (var i = 0; i < data.length; i++) {
let key = data[i].split(';')[0]; // Left hand value [Key]
let value = data[i].split(';')[1]; // Right hand value [Value]
// Add key and value to object
objects[key] = value;
}
// Access by property
console.log(objects);
Using forEach
let text = "number0;text0\nnumber1;text1\nnumber2;text2"
let data = text.split('\n');
var objects = {};
data.forEach((elem) => {
let key = elem.split(';')[0]; // Left hand value [Key]
let value = elem.split(';')[1]; // Right hand value [Value]
objects[key] = value;
});
// Access by property
console.log(objects);
Just use split again with ";", like that:
myVar = text.split(';');
like #Teemu, #Weedoze and #Alex said
Convert the array into an object
Make an object out of it with another String split. To do so you can use the .reduce method to convert the array of strings into an object.
const strings = ['number0;text0', 'number1;text1', 'number3;text3', 'number4;text4'] ;
const obj = strings.reduce((acc,curr) => {
const [key, value] = curr.split(';');
acc[key] = value;
return acc;
}, {});
console.log(obj)
This way you can access text4 buy calling obj['number4'].
More about .reduce
The reduce method works by looping through strings
on each step acc is the accumulator: it contains the object that is getting filled with key/value pairs.
cur is the current item in the step
const [key, value] = curr.split(';') will to split the string into two strings and assign each to a seperate variable: key and value. It's called destructuring assignment
then I assign the key/value pair to the accumulator
the .reducemethod will return the accumulator on his state on the last step of the loop
Something like this could do the trick:
let a = "number0;text0\nnumber1;text1\nnumber2;text2";
let lines = a.split('\n');
let vals = [];
for(let line of lines) {
vals.push(line.split(';'))
}
console.log(vals); // Output
The last four lines create an empty array and split on the ';' and append that value to the vals array. I assume you already have the something like the first 2 lines