Convert a string of comma separated numbers into a 2D array - javascript

I have a string of numbers like so:
var original = "547,449,737,452,767,421,669,367,478,367,440,391,403,392,385,405,375,421,336,447";
And I wish to convert this string into a 2D array like so:
[[547, 449] [737, 452] [767, 421] [669, 367] [478, 367] [440, 391] [403, 392] [385, 405] [375, 421] [336, 447]]
But I'm having trouble doing it. I tried using regex:
var result = original.replace(/([-\d.]+),([-\d.]+),?/g, '[$1, $2] ').trim();
But the result was a string of the following and not an array:
[547, 449] [737, 452] [767, 421] [669, 367] [478, 367] [440, 391] [403, 392] [385, 405] [375, 421] [336, 447]

Might be easier to use a global regular expression to match two segments of digits, then split each match by comma and cast to number:
var original = "547,449,737,452,767,421,669,367,478,367,440,391,403,392,385,405,375,421,336,447";
const arr = original
.match(/\d+,\d+/g)
.map(substr => substr.split(',').map(Number));
console.log(arr);

You could use split and reduce methods with % operator to create the desired result.
var original = "547,449,737,452,767,421,669,367,478,367,440,391,403,392,385,405,375,421,336,447";
const result = original.split(',').reduce((r, e, i) => {
if (i % 2 == 0) r.push([]);
r[r.length - 1].push(e);
return r;
}, [])
console.log(result)

You could look for digits with a comma in between, replace, add brakets and parse as JSON.
var original = "547,449,737,452,767,421,669,367,478,367,440,391,403,392,385,405,375,421,336,447",
array = JSON.parse('[' + original.replace(/\d+,\d+/g, '[$&]') + ']');
console.log(array);

This could be a nice use case for using .matchAll():
var original = "547,449,737,452,767,421,669,367,478,367,440,391,403,392,385,405,375,421,336,447";
var array = Array.from(original.matchAll(/(\d+),(\d+)/g),
([, ...m]) => m.map(Number));
console.log(array);

Using Regex and JSON.parse are costlier. Do it using array to matrix as below
const original = "547,449,737,452,767,421,669,367,478,367,440,391,403,392,385,405,375,421,336,447";
const arrayToMatrix = (array, columns) => Array(Math.ceil(array.length / columns)).fill('').reduce((acc, cur, index) => {
return [...acc, [...array].splice(index * columns, columns)]
}, []);
const result = arrayToMatrix(original.split(','),2);
console.log(result);

Related

How to generate a list of strings from a single string with seperators?

I want to achieve the following:
Given: A string like 'path1.path2.path3';
Wanted result: A list of strings -> [path1, path1.path2, path1.path2.path3];
The order has to be the same, I just need all the "levels". I need this to create a breadcrumb-component for an Angular-Applikation using ui-router. States do have names like "path1.path2", which means path2 is a child of path1.
The problem for me is not the splitting, I know how to achieve that via split. My problem is merging them again like mentioned above.
My first idea was to use array.split to get the single parts of the string. But I'm not sure how to build the loop to add a single partial in each iteration.
Seems like this does what you want:
'path1.path2.path3'
.split('.')
.map((section, i, arr) => [...arr.slice(0, i), section].join('.'));
It splits the strings into sections using . as the delimiter, then for each section, it joins it together with all previous sections, using . as the delimiter.
Try using a reducer for the splitted string. Something like:
const str = "path1.path2.path3";
console.log( str.split(".").reduce( (acc, str, i) =>
[...acc, (i ? `${acc[i - 1]}.${str}` : str)], []) );
There are already some answers here, but i'd like to add mine with reduce:
const string = 'path1.path2.path3'
const paths = string.split('.')
const res = paths.reduce((acc, curr) => [...acc, `${acc[acc.length-1] ? acc[acc.length-1] + '.' : ''}${curr}`], [])
console.log(res)
You could get the position of the dots and slice the array.
const
string = 'path1.path2.path3',
result = [];
let p = string.indexOf('.');
while (p !== -1) {
result.push(string.slice(0, p));
p = string.indexOf('.', p + 1);
}
result.push(string);
console.log(result);

.includes with array in Javascript

i wonder is there any way to check if in a string there are characters that match the characters in array?
const array = ["cake","hello","ok"];
const string = "hello"
let result = string.includes(array)
console.log(result)
// >false
Try to switch array and string:
const array = ["cake","hello","ok"];
const string = "hello"
let result = array.includes(string)
console.log(result)
I think you're looking for Array#some(): loop through the array and check if any of the elements match the predicate.
Here checking if string includes as a substring any of the strings in array.
const array = ["cake","hello","ok"];
const string = "helloaeeahwbdhbd"
let result = array.some(s => string.includes(s))
console.log(result)

Javascript - How to split a string into a nested array?

I know I can use split function to transform a string to an array but how can a string be split twice to produce a nested array?
I expected this would be sufficent but it does not produce the desired output.
var myString = "A,B,C,D|1,2,3,4|w,x,y,z|"
var item = myString.split("|");
var array = [item.split(",")];
Would it be more optimal to use a for each loop?
EXPECTED OUTPUT
var array = [
["A","B","C","D"],
["1","2","3","4"],
["w","x","y","z"],
];
Once you've split on |, use .map to account for the nesting before calling .split again. There's also an empty space after the last |, so to exclude that, filter by Boolean first:
const myString = "A,B,C,D|1,2,3,4|w,x,y,z|";
const arr = myString
.split('|')
.filter(Boolean)
.map(substr => substr.split(','));
console.log(arr);
Or you could use a regular expression to match anything but a |:
const myString = "A,B,C,D|1,2,3,4|w,x,y,z|";
const arr = myString
.match(/[^|]+/g)
.map(substr => substr.split(','));
console.log(arr);
var myString = "A,B,C,D|1,2,3,4|w,x,y,z"
var item = myString.split("|");
var outputArr = item.map(elem => elem.split(","));
console.log(outputArr);

Alphabetically sort array with no duplicates

I'm trying to create a function that takes an array of strings and returns a single string consisting of the individual characters of all the argument strings, in alphabetic order, with no repeats.
var join = ["test"];
var splt = (("sxhdj").split(""))
var sort = splt.sort()
var jn = sort.join("")
join.push(jn)
function removeDuplicates(join) {
let newArr = {};
join.forEach(function(x) { //forEach will call a function once for
if (!newArr[x]) {
newArr[x] = true;
}
});
return Object.keys(newArr);
}
console.log(removeDuplicates(join));
I can not get the current code to work
Check out the comments for the explanation.
Links of interest:
MDN Array.prototype.sort.
MDN Set
var splt = ("sxhdjxxddff").split("")
// You need to use localeCompare to properly
// sort alphabetically in javascript, because
// the sort function actually sorts by UTF-16 codes
// which isn't necessarily always alphabetical
var sort = splt.sort((a, b)=>a.localeCompare(b))
// This is an easy way to remove duplicates
// by converting to set which can't have dupes
// then converting back to array
sort = [...new Set(sort)]
var jn = sort.join("");
console.log(jn);
Something like this :) Hope it helps!
const string = 'aabbccd';
const array = string.split('');
let sanitizedArray = [];
array.forEach(char => {
// Simple conditional to check if the sanitized array already
// contains the character, and pushes the character if the conditional
// returns false
!sanitizedArray.includes(char) && sanitizedArray.push(char)
})
let result = sanitizedArray.join('')
console.log(result);
Try this:
const data = ['ahmed', 'ghoul', 'javscript'];
const result = [...data.join('')]
.filter((ele, i, arr) => arr.lastIndexOf(ele) === i)
.sort()
.join('');
console.log(result)
There are probably better ways to do it, one way is to map it to an object, use the keys of the object for the used letters, and than sorting those keys.
const words = ['foo', 'bar', 'funky'];
const sorted =
Object.keys(
([...words.join('')]) // combine to an array of letters
.reduce((obj, v) => obj[v] = 1 && obj, {}) // loop over and build hash of used letters
).sort() //sort the keys
console.log(sorted.join(''))

Mapping and reducing new int array issues

var strings = [ '234-496-7459', '760-644-0201', '555-222-3333' ];
var ints = [];
console.log(strings);
strings.forEach(function(entry) {
var ints = entry.replace(/-/g, '');
console.log(ints);
});
var myResults = ints.map(function (el) {
return el.toString().split('').reduce(function (sum, b) {
return sum + +b;
}, 0);
});
console.log(myResults);
I have an array of strings that I want to take out the dashes then store the new arrays as ints. I am trying to reduce each array of ints to create a myResults that print out 53, 30, 33. I know there is something wrong with this code because the mapping and reduce doesn't want to work.
You need to push entry values in ints array after replace
var strings = [ '234-496-7459', '760-644-0201', '555-222-3333' ];
var ints = [];
strings.forEach(function(entry) {
ints.push(entry.replace(/-/g, ''));
});
var myResults = ints.map(function (el) {
return el.toString().split('').reduce(function (sum, b) {
return sum + +b;
}, 0);
});
alert(myResults);
You can combine your statements like this (in a working snipppet):
var strings = [ '234-496-7459', '760-644-0201', '555-222-3333' ];
var ints = strings.map(function(item) {
return item.replace(/-/g, '').split('').reduce(function(total, val) {
return total + +val;
}, 0);
});
document.write(JSON.stringify(ints));
Explanation:
You want to convert one array to another so use .map() not .forEach().
Then, right in the .map() callback, you can convert the string to total.
.replace(/-/g, '').split('') gets rid of the dashes and turns it into an array of letters.
.reduce() then runs on that array to sum up all the digits.
If you're looking for another way, you can use
Array#map, String#replace, String#split, Array#reduce with Arrow function syntax.
You can use RegEx /\d/g with String#match to get individual numbers as an array.
var ints = arr.map(el => el.match(/\d/g, '').reduce((sum, a) => sum + +a, 0));
\d matches a single digit. g is global flag, to get all the possible matches.
var arr = ['234-496-7459', '760-644-0201', '555-222-3333'];
var ints = arr.map(el => el.match(/\d/g, '').reduce((sum, a) => sum + +a, 0));
console.log(ints);
document.write(ints);
String#replace and String#split can also be used.
var ints = arr.map(el => el.replace(/-/g, '').split('').reduce((sum, a) => sum + +a, 0));
var arr = ['234-496-7459', '760-644-0201', '555-222-3333'];
var ints = arr.map(el => el.replace(/-/g, '').split('').reduce((sum, a) => sum + +a, 0));
console.log(ints);
document.write(ints);
Equivalent code in ES5
var ints = arr.map(function (el) {
return el.replace(/-/g, '').split('').reduce(function (sum, a) {
return sum + +a;
}, 0);
});
var arr = ['234-496-7459', '760-644-0201', '555-222-3333'];
var ints = arr.map(function(el) {
return el.replace(/-/g, '').split('').reduce(function(sum, a) {
return sum + +a;
}, 0);
});
console.log(ints);
Approach this in top-down fashion, step-by-step. For each step, we will write a little spec so we are perfectly clear on what we want to do. If we write the spec well, then the JS will follow easily.
We want to write a function sum_digits_of_array, for which the spec is:
sum_digits_of_array
Given an input array, return a new array, where each element is the sum of the digits of the corresponding element from the original array.
That is exactly the definition of map, so we can write:
function sum_digits_of_array(a) { return a.map(sum_digits); }
Now we just need to write sum_digits. We will also write a spec for that:
sum_digits
Given an input string, return the sum of the digits of the string.
That's easy enough:
function sum_digits(s) { return sum(digits(s)); }
Now for digits. Again we will write a little spec for ourselves:
digits
Given a input string, return array of individual digits, as numbers.
Instead of thinking of this as removing dashes and then splitting, we will use RegExp#match to just extract the digits:
function digits(s) { return s.match(/\d/g) . map(Number); }
Then
sum
Given an array of numbers, return the sum of all the numbers.
This is the definition of reduce, so
function sum(a) { return a.reduce(add); }
Then
add
Given two numbers, return the result of adding them
function add(a, b) { return a + b; }
That's it. So the entire solution, which is slightly more compact if we use ES6 arrow functions:
function sum_digits_of_array(a) {
const sum_digits = s => sum(digits(s));
const digits = s => s.match(/\d/g) . map(Number);
const sum = a => a . reduce(add);
const add = (a, b) => a + b;
return a . map(sum_digits);
}
Why code in this fashion? There are a number of good reasons.
You can read the code and tell what it's doing.
Related to that, it's easy to figure out where to modify the code if the problem changes.
We can easily test each little function to make sure it's working right.
The little functions we wrote might come in handy when solving a related problem, so we reduce the amount of work we have to do in the future.

Categories

Resources