Sorting Javascript Array with Split Function - javascript

I have an array that looks like this
var testArray = ['name1:13', 'name2:15', 'name3:13'];
I would like to sort the array by the number to the right of the colon.
So far I have this:
var converted = testArray.map(
function (item) {
return item.split(':').map(
function (num) {
return parseInt(num);
});
})
alert(converted)
var sorted = converted.sort(function (a, b) { return a[1] - b[1] })
alert(sorted);
That sorts them in the correct order but I'm not sure how to pass over the first part of each string, the part to the left of the colon.
Right now it returns: NAN,13,NAN,13,NAN,15

Make a helper function to access the [1]st index of the split result, then in the sort callback, call that function for both and return the difference:
var testArray = ['name1:13', 'name2:15', 'name3:13'];
const getVal = str => str.split(':')[1];
testArray.sort((a, b) => getVal(a) - getVal(b));
console.log(testArray);

Split, convert to number and compare.
var testArray = ["name1:13", "name2:15", "name3:13"];
const sortFunction = (a, b) => {
const value = str => Number(str.split(":")[1]);
return value(a) - value(b);
};
testArray.sort(sortFunction);
console.log(testArray);

var testArray = ['name1:13', 'name2:15', 'name3:13'];
console.log(testArray.sort((a, b) => (a.split(":")[1] > b.split(":")[1]) ? 1 : -1))

Related

Counting letters and numbers in string

I write a code that works with letter but not with numbers
I know it maybe a little complicated but this is how I could do it;
with numbers it produce ordered Array and I don't know why
var orderedCount = function(text) {
let splitted = text.split('');
let countedLetters = splitted.reduce((AllLetters, letter) => {
(letter in AllLetters) ? AllLetters[letter]++: AllLetters[letter] = 1;
return AllLetters
}, {})
let result = Object.keys(countedLetters).map((key) => {
return [(key), countedLetters[key]]
})
return result;
};
console.log(orderedCount("abracadabra")); //[['a',5], ['b',2], ['r',2], ['c',1], ['d',1]]
console.log(orderedCount("212")); //[['1',1], ['2',2]]
[['1',1],['2',2]]
should be
[['2',2],['1',1]]
You can use Object.entries to convert the object into an array and use sort to sort the element 1
var orderedCount = function(text) {
let splitted = text.split('');
let countedLetters = splitted.reduce((AllLetters, letter) => {
(letter in AllLetters) ? AllLetters[letter]++: AllLetters[letter] = 1;
return AllLetters
}, {})
let result = Object.entries(countedLetters).sort((a, b) => {
return b[1] - a[1];
})
return result
};
console.log(orderedCount("abracadabra"));
console.log(orderedCount("212"));
Shorter Version:
var orderedCount = function(text) {
return Object.entries(text.split('').reduce((c, v) => {
c[v] = (c[v] || 0) + 1;
return c;
}, {})).sort((a, b) => b[1] - a[1]);
};
console.log(orderedCount("abracadabra"));
console.log(orderedCount("212"));
You can create the array directly using Array#reduce method where use a reference object which keeps object reference based on letter value.
var orderedCount = function(text) {
const ref = {};
return text.split('').reduce((arr, letter) => {
(letter in ref) ? ref[letter][1]++: arr.push(ref[letter] = [letter, 1]);
return arr;
}, []);
};
console.log(orderedCount("abracadabra")); //[['a',5], ['b',2], ['r',2], ['c',1], ['d',1]]
console.log(orderedCount("212")); //[['1',1], ['2',2]]
Refer : Does JavaScript Guarantee Object Property Order?
Since es2015 onwards non-integer keys are kept inserting order and integer keys are sorted numerically.
You need to sort you result by count, because by default numeric keys in Object will be in ascending order
var orderedCount = function(text) {
let splitted = text.split('');
let countedLetters = splitted.reduce((AllLetters, letter) => {
(letter in AllLetters) ? AllLetters[letter]++: AllLetters[letter] = 1;
return AllLetters
}, {})
let result = Object.keys(countedLetters).map((key) => {
return [(key), countedLetters[key]]
})
return result.sort((a,b)=>b[1] - a[1]);
};
console.log(orderedCount("abracadabra")); //[['a',5], ['b',2], ['r',2], ['c',1], ['d',1]]
console.log(orderedCount("212")); //[['1',1], ['2',2]]

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

Regex: Match same expression multiple times and return full string before expression

I have a string looking like this:
/a/b/entry/0/c/d/entry/0
I would like to match /entry/0 with /entry/[0-9]+. For each occurrence
individually and return an array
["/a/b/entry/0/", "/a/b/entry/0/c/d/entry/0"]
for arbitrary number of occurrences of /entry/[0-9]+ in the string.
Also note that i would like to keep the expression in the output string.
Is this possible using a single Regex expression and the string.match or string.split function in JavaScript?
You can use split and reduce as well.
var input = "/a/b/entry/0/c/d/entry/0";
var output = input.split( /(?<=entry\/[0-9]+)/ )
.reduce( (a, c) => {
a.push( (a[a.length - 1] || "") + c ); //push new item after appending c to last item in accumulator
return a; return accumulator
} ,[])//initialize accumulator
Demo
var input = "/a/b/entry/0/c/d/entry/0";
var output = input.split(/(?<=entry\/[0-9]+)/)
.reduce((a, c) => {
a.push((a[a.length - 1] || "") + c); //push new item after appending c to last item in accumulator
return a;
return accumulator
}, []) //initialize accumulator
console.log(output);
Edit
Use #Wiktor's suggestion to match and then reduce
var input = "/a/b/entry/0/c/d/entry/0";
var output = (input.match(/.*?\/entry\/\d+(?:\/|$)/g) || []) //check for null
.reduce( (a, c) => {
a.push( (a[a.length - 1] || "") + c ); //push new item after appending c to last item in accumulator
return a; return accumulator
} ,[])//initialize accumulator

How to sort and list out the array element, after comparing the sums of each numeric value

This code returns only returns the order of the sums of the numeric value, how do I return the array element in a list arranged by largest sum on top?
For instance, the result should be:
"1234-2722-2343-2842"
"1234-2722-2343-2345"
"1234-2322-2343-2342"
Code:
var addSum = function(ccNum) {
var sum = 0;
for (var i=0; i<ccNum.length; i++ ) {
var eachLetter = ccNum.charAt(i);
if (!isNaN(eachLetter)) {
sum += +eachLetter;
}
}
return sum;
};
var ccNums = ["1234-2322-2343-2342","1234-2722-2343-2345", "1234-2722-2343-2842"];
var checkNums = [];
for (var i=0; i<ccNums.length; i++) {
var ccNum = ccNums[i];
var sum = addSum(ccNum);
console.log("The checksum of CC number:"+ccNum+" is "+sum);
checkNums.push(sum);
}
checkNums.sort(function(a,b) {
return b-a;
});
console.log(checkNums);
The solution using String.replace, String.split, Array.map, Array.filter and Array.reduce:
var ccNums = ["1234-2322-2343-2342","1234-2722-2343-2345", "1234-2722-2343-2842"],
getSum = function(num){
return num.replace("-", "").split("").map(Number).filter(Boolean).reduce(function(prev, next){
return prev + next;
});
};
ccNums.sort(function (a, b) {
return getSum(b) - getSum(a);
});
console.log(ccNums);
The output:
["1234-2722-2343-2842", "1234-2722-2343-2345", "1234-2322-2343-2342"]
I suggest use Sorting with map, because it uses only one iteration for the sum of a string and uses it until the sorts end. Then it rebuilds a new array with the sorted items.
var ccNums = ["1234-2322-2343-2342", "1234-2722-2343-2345", "1234-2722-2343-2842"];
// temporary array holds objects with position and sort-value
var mapped = ccNums.map(function (el, i) {
return {
index: i,
value: el.split('').reduce(function (r, a) { return r + (+a || 0); }, 0)
};
});
// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
return b.value - a.value;
});
// container for the resulting order
var result = mapped.map(function (el) {
return ccNums[el.index];
});
console.log(result);
Use Array#sort with help of String#split and Array#reduce methods
var ccNums = ["1234-2322-2343-2342", "1234-2722-2343-2345", "1234-2722-2343-2842"];
// function to get sum of numbers in string
function sum(str) {
// split string
return str.split('-')
// iterate and get sum
.reduce(function(a, b) {
// parse string to convert to number
return a + Number(b); // in case string contains no-digit char that for avoiding NaN use "return a + ( parseInt(b, 10) || 0 )
}, 0); //set initial value to avoid 2 parsing
}
// call sort function
ccNums.sort(function(a, b) {
// find out sum and compare based on that
return sum(b) - sum(a);
});
console.log(ccNums)
Or much better way would be, store the sum in an object and refer in sort function which helps avoid calling sum function multiple times.
var ccNums = ["1234-2322-2343-2342", "1234-2722-2343-2345", "1234-2722-2343-2842"];
// function to get sum of numbers in string
function sum(str) {
// split string
return str.split('-')
// iterate and get sum
.reduce(function(a, b) {
// parse string to convert to number
return a + Number(b);
}, 0); //set initial value to avoid 2 parsing
}
var sumArr = {};
// create object for referncing sum,
// which helps to avoid calling sum function
// multiple tyms with same string
ccNums.forEach(function(v) {
sumArr[v] = sum(v);
});
// call sort function
ccNums.sort(function(a, b) {
// find out sum and compare based on that
return sumArr[b] - sumArr[a];
});
console.log(ccNums)

Sort an array by its values

I have the following array.
var arr = ["1-5", "3-6", "2-4"];
Is there a way where I can sort like this:
var arr = ["1-5", "2-4", "3-6"]
I've tried with jquery map but cant because the values of array are not Numbers.
You can use sort function
Sort by first number
arr.sort(function (a, b) {
// a.split('-') - split a string into an array - ['1', '5']
// a.split('-')[0] - get first element - '1'
// "+" converts string to number - 1
// the same for "b"
return +a.split('-')[0] - +b.split('-')[0];
});
Example
Sort by second number
arr.sort(function (a, b) {
return +a.split('-')[1] - +b.split('-')[1];
});
Example
Use array sort. First the first num is compared. If they are equal, the second num is compared..
var arr = ["1-5", "3-6", "2-4"];
var sorted = arr.sort(function(a,b){
var numsA = a.split('-');
var numsB = b.split('-');
if (numsA[0]-numsB[0] !== 0){
return numsA[0] - numsB[0];
}
return numsA[1] - numsB[1];
});
document.write(sorted);
You can try the built in sort functionality arr.sort()
http://jsfiddle.net/qctg9cfx/
If sorting by the first number in the string, and also if the first number could itself be negative then a more robust solution may be to use parseInt.
var arr = ["1-5", "3-6", "-1-3", "2-4"];
arr.sort(function (a, b) {
return parseInt(a, 10) - parseInt(b, 10);
});
document.body.appendChild(document.createTextNode(JSON.stringify(arr)));

Categories