How to separate array of comma separated string into various arrays? - javascript

What's the best way to convert this array of comma separated values
[ 'com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on' ]
Into three arrays?
[ 'com--test', [ LFutx9mQbTTyRo4A9Re5Ilsdf4cKN4q2', ['on',
'com--fxtrimester', SEzMpW3FxkSbzL7eo5MmlkdfqkPczCl2', 'on',
'com--fxtrimester' ] LFutksdfx9mQbTTyRo4A9Re5I4cKN4q2 ] 'on']
I was trying something like:
var indexToSplit = unique.indexOf(',');
var status = unique.slice(3, indexToSplit - 1);
var use = unique.slice(2, indexToSplit - 2);
var pros = unique.slice(0, indexToSplit - 3);
console.log(pros);
But I figured that is wrong ... any help is appreciated!

You will have to loop over array and use string.split to get seperate parts.
Once you have seperate parts, you can push them to necessary array;
var d = [ 'com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on'];
var result = [[],[],[]];
var len = 3;
d.forEach(function(str, i){
var _tmp = str.split(',');
for (var i = 0; i<len; i++){
result[i].push(_tmp[i])
}
})
console.log(result)
A little generic way.
Loop over data and split each string using comma(,)
Loop over split values and check if necessary array exists.
If not, initialise array, but you cannot do p[i] = [] as this will push to first value. You will have to also initialise all previous values. For this, you can use new Array(length). By default, if length is greater than 0, all indexes will be initialise to undefined.
Now push to necessary array. Position will be maintained.
var d = ['com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on,test'
];
var result = d.reduce(function(p, c, index) {
var _tmp = c.split(',');
for (var i = 0; i < _tmp.length; i++) {
// Check if position not defined.
if (p[i] === undefined)
// Initialize array and add default (undefined) to all elements before current element
p[i] = new Array(index);
p[i].push(_tmp[i])
}
return p;
}, [])
console.log(result)

With map this becomes:
for positions X out of 0, 1 and 2:
convert each item in the list into an array, and choose the Xth item
var start = [ 'com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on' ]
var out = [0,1,2].map(i =>
start.map(x => x.split(',')[i]) )
console.log(out)

Since your question does not ask for a more general case, i am safely assuming it for 3 array. We can use forEach function on array below code can be one amongst the possible solutions
var arr1 = [];
var arr2 = [];
var arr3 = [];
var x = ['com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on', 'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on', 'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on']
x.forEach(function(data) {
var dataArray = data.split(',');
arr1.push(dataArray[0]);
arr2.push(dataArray[1]);
arr3.push(dataArray[2]);
});
console.log(arr1)
console.log(arr2)
console.log(arr3)

Related

Unsplit two arrays Javascript

I have the following code
var Louis = [ 'Louis.IX', 'Louis.VIII' ]
var array1 = [];
var array2 = [];
for (var i = 0; i < Louis.length; i++) {
var split = Louis[i].split(".");
array1.push(split[0]); // before the dot
array2.push(split[1]); // after the dot
}
console.log("Louisname", array1);
console.log("Louisnum", array2);
and the output is
Louisname [ 'Louis', 'Louis' ]
Louisnum [ 'IX', 'VIII' ]
Now any idea on how can i revert the output into the initial array? Please help me, thanks.
You can use .map() with its second index argument to join elements in the first array with the second array by returning a string which contains elements in both arrays like so:
const array1 = ["Louis", "Louis"];
const array2 = ["IX","VIII"];
const original = array1.map((v, i) => `${v}.${array2[i]}`);
console.log(original);
If you're new to JS, here is a more straightforward/imperative way of achieving the same result (see code comments for details):
const array1 = ["Louis", "Louis"];
const array2 = ["IX","VIII"];
const original = [];
for(let i = 0; i < array1.length; i++) { // loop through all elements in array 1
const original_str = array1[i] + "." + array2[i]; // join array element `i` in array1 with array element `i` in array2
original.push(original_str); // add the joined string to the `original` array
}
console.log(original);

Remove Duplicate elements from Array - Javascript (No JQuery & ECMAScript)

Case: We have 'n' number of arrays stored in an array (Array of Arrays). Now that each child array in this parent array can have elements that may or may not be present in other child arrays. Output - I need to create an array which has the all the elements present in all the child arrays excluding the duplicates.
I do not want to concatenate all the arrays into a single array and use unique method to filter out. I need to create unique array then and there during iteration.
Ex:
var a[] = [1,2,3,4,5];
var b[] = [1,2,7,8];
var c[] = [1,2,3,4,5,6,7,8];
var d[] = [9,10,11,12];
var arr[] = [a,b,c,d]
Output must be [1,2,3,4,5,6,7,8,9,10,11,12]
P.S: I can concat the arrays and use jquery unique function to resolve this, but i need a solution in javascript alone. Thanks
You can use array#reduce to flatten your array and then use Set to get distinct values and use array#from to get back array from Set.
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var arr = [a,b,c,d]
var result = Array.from(new Set(arr.reduce((r,a) => r.concat(a))));
console.log(result);
Try using .filter when adding each array to the final one, filtering out the duplicates:
a.filter(function(item) {
return !finalArray.contains(item));
});
Answer using Sets:
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var concat = a.concat(b).concat(c).concat(d);
var union = new Set(concat);
//console.log(union);
ES6 Answer:
let a = new Set([1,2,3,4,5]);
let b = new Set([1,2,7,8]);
let c = new Set([1,2,3,4,5,6,7,8]);
let d = new Set([9,10,11,12]);
let arr = new Set([...a,...b,...c,...d]);
//Result in arr.
Whats going on???
From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set:
The Set object lets you store unique values of any type, whether
primitive values or object references.
So when we initialise Sets passing arrays to the constructor we basically ensure that there are no duplicate values.
Then in the last line, we concat all the Sets we initialised prior into a final set.
The ... notation converts the Set into an array, and when we pass the 4 arrays to the constructor of the Set they get concatenated and a Set of their unique values is created.
Here is a functional alternative written in ES5.
var flatten = function(list) {
return list.reduce(function(acc, next) {
return acc.concat(Array.isArray(next) ? flatten(next) : next);
}, []);
};
var unique = function(list) {
return list.filter(function(element, index) {
return list.indexOf(element) === index;
})
}
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var arr = [a,b,c,d];
var result = unique(flatten(arr));
console.log(result);
If you support ES6, arrow function can make that code even shorter.
Here is a solution that uses a plain object for resolving duplicates, and only uses basic ES3 JavaScript. Runs in IE 5.5 and higher, and with O(n) time complexity.
function uniques(arr) {
var obj = {}, result = [];
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = true;
}
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) result.push(+prop);
}
return result;
}
// Example use
var a = [1,2,3,4,5],
b = [1,2,7,8],
c = [1,2,3,4,5,6,7,8],
d = [9,10,11,12];
var result = uniques(a.concat(b, c, d));
console.log('Result: ' + result);
As an object can only have a unique set of properties (no duplicates), the use of all array values as properties in an object will give you an object with a property for each unique value. This happens in the first loop. NB: the value given to those properties is not relevant; I have used true.
Then the result is just the conversion of those properties back to array values. This happens in the second loop.
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var result = a.concat(b,c,d);
function remvDup(result){
var tmp = [];
for(var i = 0; i < result.length; i++){
if(tmp.indexOf(result[i]) == -1){
tmp.push(result[i]);
}
}
return tmp;
}
console.log(remvDup(result));
Becuase the OP mentioned that he cannot use 'Set' as it is not supported on the targeted browsers, I would recommand using the 'union' function from the lodash library.
See union's documentation here

Javascript 2D array getting each element

I have a 2D array that looks like:
var example = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]];
I'd like to iterate through the array and take out 'V1.0' and 'V2.0' and store them in their own new array, and do the same for '1' and '2'. I need to break the data up for use with Chart.js
My loop looks like this:
var labels = [];
var data = [];
for (var i=0; i<example.length; i++) {
labels.push = (example[i][0]);
}
for (var j=0; j<example.length; j++) {
data.push = (example[0][j]);
}
I don't know how to properly get either element into their own array for use later.
You can use map to do this, and shift the result in order to remove the first occurence.
var example = [
['Version', 'Number'],
['V1.0', 1],
['V2.0', 2]
];
var result = example.map(e => e[0])
console.log(result);
From what I saw into your example the first pair of elements are the keys for your data, into your example will include them into your final arrays.
This example will generate to a dictionary with the keys Number and Version containing the corresponding values from your array.
var example = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]];
function extract(items) {
var keys = {},
version = items[0][0],
number = items[0][1];
keys[version] = [];
keys[number] = [];
return items.slice(1).reduce(function(acc, item) {
acc[version].push(item[0]);
acc[number].push(item[1]);
return acc;
}, keys);
}
var result = extract(example);
console.log(result);
From this point you can do something like:
var labels = result.Version;
var data = result.Number;
This looks like what you are trying to achieve:
for(var i=0; i<example.length; i++){
labels.push(example[i][0])
data.push(example[i][1])
}

Split nested array into multiple arrays

I have a string that looks like this:
str = {1|2|3|4|5}{a|b|c|d|e}
I want to split it into multiple arrays. One containing all the first elements in each {}, one containing the second element, etc. Like this:
arr_0 = [1,a]
arr_1 = [2,b]
arr_2 = [3,c]
.....
The best I can come up with is:
var str_array = str.split(/}{/);
for(var i = 0; i < str_array.length; i++){
var str_row = str_array[i];
var str_row_array = str_row.split('|');
arr_0.push(str_row_array[0]);
arr_1.push(str_row_array[1]);
arr_2.push(str_row_array[2]);
arr_3.push(str_row_array[3]);
arr_4.push(str_row_array[4]);
}
Is there a better way to accomplish this?
Try the following:
var zip = function(xs, ys) {
var out = []
for (var i = 0; i < xs.length; i++) {
out[i] = [xs[i], ys[i]]
}
return out
}
var res = str
.split(/\{|\}/) // ['', '1|2|3|4|5', '', 'a|b|c|d|e', '']
.filter(Boolean) // ['1|2|3|4|5', 'a|b|c|d|e']
.map(function(x){return x.split('|')}) // [['1','2','3','4','5'], ['a','b','c','d','e']]
.reduce(zip)
/*^
[['1','a'],
['2','b'],
['3','c'],
['4','d'],
['5','e']]
*/
Solution
var str = '{1|2|3|4|5}{a|b|c|d|e}'.match(/[^{}]+/g).map(function(a) {
return a.match(/[^|]+/g);
}),
i,
result = {};
for (i = 0; i < str[0].length; i += 1) {
result["arr_" + i] = [+str[0][i], str[1][i]];
}
How it works
The first part, takes the string, and splits it into the two halves. The map will return an array after splitting them after the |. So str is left equal to:
[
[1,2,3,4,5],
['a', 'b', 'c', 'd', 'e']
]
The for loop will iterate over the [1,2,3,4,5] array and make the array with the appropriate values. The array's are stored in a object. The object we are using is called result. If you don't wish for it to be kept in result, read Other
Other
Because you can't make variable names from another variable, feel free to change result to window or maybe even this (I don't know if that'll work) You can also make this an array
Alternate
var str = '{1|2|3|4|5}{a|b|c|d|e}'.match(/[^{}]+/g).map(function(a) { return a.match(/[^|]+/g); }),
result = [];
for (var i = 0; i < str[0].length; i += 1) {
result[i] = [+str[0][i], str[1][i]];
}
This is very similar except will generate an Array containing arrays like the other answers,

Javascript natural sort array/object and maintain index association

I have an array of items as follows in Javascript:
var users = Array();
users[562] = 'testuser3';
users[16] = 'testuser6';
users[834] = 'testuser1';
users[823] = 'testuser4';
users[23] = 'testuser2';
users[917] = 'testuser5';
I need to sort that array to get the following output:
users[834] = 'testuser1';
users[23] = 'testuser2';
users[562] = 'testuser3';
users[823] = 'testuser4';
users[917] = 'testuser5';
users[16] = 'testuser6';
Notice how it is sorted by the value of the array and the value-to-index association is maintained after the array is sorted (that is critical). I have looked for a solution to this, tried making it, but have hit a wall.
By the way, I am aware that this is technically not an array since that would mean the indices are always iterating 0 through n where n+1 is the counting number proceeding n. However you define it, the requirement for the project is still the same. Also, if it makes a difference, I am NOT using jquery.
The order of the elements of an array is defined by the index. So even if you specify the values in a different order, the values will always be stored in the order of their indices and undefined indices are undefined:
> var arr = [];
> arr[2] = 2;
> arr[0] = 0;
> arr
[0, undefined, 2]
Now if you want to store the pair of index and value, you will need a different data structure, maybe an array of array like this:
var arr = [
[562, 'testuser3'],
[16, 'testuser6'],
[834, 'testuser1'],
[823, 'testuser4'],
[23, 'testuser2'],
[917, 'testuser5']
];
This can be sorted with this comparison function:
function cmp(a, b) {
return a[1].localeCompare(b[1]);
}
arr.sort(cmp);
The result is this array:
[
[834, 'testuser1'],
[23, 'testuser2'],
[562, 'testuser3'],
[823, 'testuser4'],
[917, 'testuser5'],
[16, 'testuser6']
]
If I understand the question correctly, you're using arrays in a way they are not intended to be used. In fact, the initialization style
// Don't do this!
var array = new Array();
array[0] = 'value';
array[1] = 'value';
array[2] = 'value';
teaches wrong things about the nature and purpose of arrays. An array is an ordered list of items, indexed from zero up. The right way to create an array is with an array literal:
var array = [
'value',
'value',
'value'
]
The indexes are implied based on the order the items are specified. Creating an array and setting users[562] = 'testuser3' implies that there are at least 562 other users in the list, and that you have a reason for only knowing the 563rd at this time.
In your case, the index is data, and is does not represent the order of the items in the set. What you're looking for is a map or dictionary, represented in JavaScript by a plain object:
var users = {
562: 'testuser3',
16: 'testuser6',
834: 'testuser1',
823: 'testuser4',
23: 'testuser2',
917: 'testuser5'
}
Now your set does not have an order, but does have meaningful keys. From here, you can follow galambalazs's advice to create an array of the object's keys:
var userOrder;
if (typeof Object.keys === 'function') {
userOrder = Object.keys(users);
} else {
for (var key in users) {
userOrder.push(key);
}
}
…then sort it:
userOrder.sort(function(a, b){
return users[a].localeCompare(users[b]);
});
Here's a demo
You can't order arrays like this in Javascript. Your best bet is to make a map for order.
order = new Array();
order[0] = 562;
order[1] = 16;
order[2] = 834;
order[3] = 823;
order[4] = 23;
order[5] = 917;
In this way, you can have any order you want independently of the keys in the original array.
To sort your array use a custom sorting function.
order.sort( function(a, b) {
if ( users[a] < users[b] ) return -1;
else if ( users[a] > users[b] ) return 1;
else return 0;
});
for ( var i = 0; i < order.length; i++ ) {
// users[ order[i] ]
}
[Demo]
Using the ideas from the comments, I came up with the following solution. The naturalSort function is something I found on google and I modified it to sort a multidimensional array. Basically, I made the users array a multidimensional array with the first index being the user id and the second index being the user name. So:
users[0][0] = 72;
users[0][1] = 'testuser4';
users[1][0] = 91;
users[1][1] = 'testuser2';
users[2][0] = 12;
users[2][1] = 'testuser8';
users[3][0] = 3;
users[3][1] = 'testuser1';
users[4][0] = 18;
users[4][1] = 'testuser7';
users[5][0] = 47;
users[5][1] = 'testuser3';
users[6][0] = 16;
users[6][1] = 'testuser6';
users[7][0] = 20;
users[7][1] = 'testuser5';
I then sorted the array to get the following output:
users_sorted[0][0] = 3;
users_sorted[0][1] = 'testuser1';
users_sorted[1][0] = 91;
users_sorted[1][1] = 'testuser2';
users_sorted[2][0] = 47;
users_sorted[2][1] = 'testuser3';
users_sorted[3][0] = 72;
users_sorted[3][1] = 'testuser4';
users_sorted[4][0] = 20;
users_sorted[4][1] = 'testuser5';
users_sorted[5][0] = 16;
users_sorted[5][1] = 'testuser6';
users_sorted[6][0] = 18;
users_sorted[6][1] = 'testuser7';
users_sorted[7][0] = 12;
users_sorted[7][1] = 'testuser8';
The code to do this is below:
function naturalSort(a, b) // Function to natural-case insensitive sort multidimensional arrays by second index
{
// setup temp-scope variables for comparison evauluation
var re = /(-?[0-9\.]+)/g,
x = a[1].toString().toLowerCase() || '',
y = b[1].toString().toLowerCase() || '',
nC = String.fromCharCode(0),
xN = x.replace( re, nC + '$1' + nC ).split(nC),
yN = y.replace( re, nC + '$1' + nC ).split(nC),
xD = (new Date(x)).getTime(),
yD = xD ? (new Date(y)).getTime() : null;
// natural sorting of dates
if ( yD )
if ( xD < yD ) return -1;
else if ( xD > yD ) return 1;
// natural sorting through split numeric strings and default strings
for( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
if (oFxNcL < oFyNcL) return -1;
else if (oFxNcL > oFyNcL) return 1;
}
return 0;
}
// Set values for index
var users = Array();
var temp = Array();
users.push(Array('72', 'testuser4'));
users.push(Array('91', 'testuser2'));
users.push(Array('12', 'testuser8'));
users.push(Array('3', 'testuser1'));
users.push(Array('18', 'testuser7'));
users.push(Array('47', 'testuser3'));
users.push(Array('16', 'testuser6'));
users.push(Array('20', 'testuser5'));
// Sort the array
var users_sorted = Array();
users_sorted = users.sort(naturalSort);
I'd use map once to make a new array of users,
then a second time to return the string you want from the new array.
var users= [];
users[562]= 'testuser3';
users[16]= 'testuser6';
users[834]= 'testuser1';
users[823]= 'testuser4';
users[23]= 'testuser2';
users[917]= 'testuser5';
var u2= [];
users.map(function(itm, i){
if(itm){
var n= parseInt(itm.substring(8), 10);
u2[n]= i;
}
});
u2.map(function(itm, i){
return 'users['+itm+']= testuser'+i;
}).join('\n');
/*returned value: (String)
users[834]= testuser1
users[23]= testuser2
users[562]= testuser3
users[823]= testuser4
users[917]= testuser5
users[16]= testuser6
*/
If you want to avoid any gaps. use a simple filter on the output-
u2.map(function(itm, i){
return 'users['+itm+']= testuser'+i;
}).filter(function(itm){return itm}).join('\n');
Sparse arrays usually spell trouble. You're better off saving key-value pairs in an array as objects (this technique is also valid JSON):
users = [{
"562": "testuser3"
},{
"16": "testuser6"
}, {
"834": "testuser1"
}, {
"823": "testuser4"
}, {
"23": "testuser2"
}, {
"917": "testuser5"
}];
As suggested, you can use a for loop to map the sorting function onto the array.
Array.prototype.sort() takes an optional custom comparison function -- so if you dump all of your users into an array in this manner [ [562, "testuser3"], [16, "testuser6"] ... etc.]
Then sort this array with the following function:
function(comparatorA, comparatorB) {
var userA = comparatorA[1], userB = comparatorB[1]
if (userA > userB) return 1;
if (userA < userB) return -1;
if (userA === userB) return 0;
}
Then rebuild your users object. (Which will loose you your sorting.) Or, keep the data in the newly sorted array of arrays, if that will work for your application.
A oneliner with array of array as a result:
For sorting by Key.
let usersMap = users.map((item, i) => [i, item]).sort((a, b) => a[0] - b[0]);
For sorting by Value. (works with primitive types)
let usersMap = users.map((item, i) => [i, item]).sort((a, b) => a[1] - b[1]);

Categories