Sorting an Array of comma separated string using JavaScript - 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);

Related

How to simply find matching values in [[], [], []] arrays in javascript

new to javascript. i have these two arrays
var array1 = [['1'],['2']];
var array2 = [['2'],['3'],['4']];
how can i find the matching values?
tried below but returns empty array probably because it's for normal array structure ['', '', '']
var matchingValue = array1.filter(value => array2.includes(value));
Logger.log(matchingValue);
Matching value should be ['2']
You can simply use .flat() to flatten the arrays so you only deal with the values like so :-
var array1 = [['1'],['2']];
var array2 = [['2'],['3'],['4']];
var matchingValue = array1.flat().filter((value) => array2.flat().includes(value) )
console.log(matchingValue);
First, let's have a function that tells if two arrays are equal:
let equal = (a, b) => a.length === b.length && a.every((_, i) => a[i] === b[i])
Then, use this function to find an intersection of two arrays:
var array1 = [['1'],['2']];
var array2 = [['2'],['3'],['4']];
let equal = (a, b) => a.length === b.length && a.every((_, i) => a[i] === b[i])
result = array1.filter(x => array2.some(y => equal(x, y)))
console.log(result)
In a more generic way, you can write intersectBy that would compute an intersection using a predicate callback:
let intersectBy = (a, b, predicate) =>
a.filter(x => b.some(y => predicate(x, y)))
Array.includes compares by identity, so it works with primitives and not with Array and Objects.
This is a solution that compares the first element of the internal arrays:
var matchingValue = array1.filter(value1 => {
return array2.map(value2 => value2[0]).includes(value1[0]);
});
Array.map is used to convert an Array of Arrays in Array of strings, then Array.includes is used to match the first element of first Array.
This works only with the current structure (arrays of one element arrays).
const array1 = [['1'],['2']];
const array2 = [['2'],['3'],['4']];
const array1Flat = [].concat(...array1);
const array2Flat = [].concat(...array2);
const matchingValue = array1Flat.filter((value) => array2Flat.includes(value));
console.log(matchingValue);
You don't need to use .flat() you can simply use concat and spread to flatten the array.

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);

How to make an average of nested array

I'm trying to make an average array of a bigger and dynamic array. Simpler looks like this:
const bigArr = [[[1,1,1], [2,2,2], [3,3,3]],[[3,3,3], [4,4,4], [7,7,7]]]
in the end, I'm expecting to get:
const averageArray = [[2,2,2], [3,3,3], [5,5,5]]
I know the best way is to triple loop over this array's, but I couldn't manage to get expected result.
averageArray[0][0] is an average of bigArr[0][0] and bigArr[1][0].
There are a few ways to do it (for loops, reduce, etc.) here I show an example with reduce:
const bigArr = [
[[1,1,1], [2,2,2], [3,3,3]],
[[3,3,3], [4,4,4], [7,7,7]],
//[[5,5,5], [6,6,6], [11,11,11]]
];
const averageArray = bigArr.reduce((aggArr, arr, i) => {
if (i == 0){
return arr.map( a => a );
}
else {
arr.forEach( (a, j) => {
a.forEach( (b, k) => {
aggArr[j][k] = ((aggArr[j][k] * i) + b) / (i + 1)
})
});
}
return aggArr;
}, []);
console.log(averageArray);
Output:
[[2,2,2], [3,3,3], [5,5,5]]
It would also work with a larger input like this:
const bigArr = [
[[1,1,1], [2,2,2], [3,3,3]],
[[3,3,3], [4,4,4], [7,7,7]],
[[5,5,5], [6,6,6], [11,11,11]]
];
We get this output:
[[3,3,3], [4,4,4], [7,7,7]]
One final example:
It would also work with a larger input with non identical sub-arrays like this (to illustrate how the averaging is occurring):
const bigArr = [
[[1,2,3], [1,2,3], [1,2,3]],
[[3,4,7], [3,4,7], [3,4,7]],
[[5,6,11], [5,6,11], [5,6,11]]
];
We get this output:
[[3,4,7], [3,4,7], [3,4,7]]

Convert javascript string to array

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);

Sorting string arrays based on the number present in the element

I have to sort a string array based on the number.
Example
["1.READ","10.CREATE","3.sfg","2.dfd","12.dqwe"];
Desired Result
["1.READ","2.dfd","3.sfg","10.CREATE","12.dqwe"];
My Code
var arr = ["1.READ","10.CREATE","3.sfg","2.dfd","12.dqwe"];
var arr2 = arr.map( a => a.split('.').map( n => +n+100000 ).join('.') ).sort().map( a => a.split('.').map( n => +n-100000 ).join('.') );
console.log(arr);
console.log(arr2);
You can just split and convert the first element to Number
var arr = ["1.READ", "10.CREATE", "3.sfg", "2.dfd", "12.dqwe"];
var arr2 = arr.sort((a, b) => {
return Number(a.split(".")[0]) - Number(b.split(".")[0]);
});
console.log(arr2);
The code above will also sort the first variable. If you you only want arr2 to be sorted, you can:
var arr = ["1.READ", "10.CREATE", "3.sfg", "2.dfd", "12.dqwe"];
var arr2 = [...arr]; //Spread the array so that it will not affect the original
arr2.sort((a, b) => {
return Number(a.split(".")[0]) - Number(b.split(".")[0]);
});
console.log(arr);
console.log(arr2);
You could split and take only the first part. Then take the delta for sorting.
var array = ["1.READ", "10.CREATE", "3.sfg", "2.dfd", "12.dqwe"];
array.sort((a, b) => a.split(".")[0] - b.split(".")[0]);
console.log(array);
Here it is:
var arr = ["1.READ","10.CREATE","3.sfg","2.dfd","12.dqwe"];
arr.sort(function(a, b) {
return a.split('.')[0] - b.split('.')[0];
});
console.log(arr)
// ["1.READ", "2.dfd", "3.sfg", "10.CREATE", "12.dqwe"]
This answer base on built in array sort function, with customizable compare logic.
Check this out for more detail: Javascript Array Sort
Cheers,

Categories