Extract element having highest attribute value - javascript

I have below object, which can have many careerLevels (I have shown 2 for now):
var input =
{
"careerLevel": "Associate",
"careerLevels": [
{
"201609": 21,
"201610": 22,
"201611": 23,
"careerID": "10000120"
},
{
"201609": 31,
"201610": 32,
"201611": 33,
"careerID": "10000130"
}]
};
I want to check careerID attribute and i need to extract that element which has highest careerID value.
So in this case the output will look like :
var output= {"201609": 31,
"201610": 32,
"201611": 33}
What i have tried is as below :
var res = Math.max.apply(Math, oldArr.careerLevels.map(function (o) { return o.careerID; })) // This gives me the highest careerID value
var highestOrderArr = oldArr.careerLevels.filter(element => {
// i think here i need to make a check for the comparison
});

We can use reduce, to get the highest careerID and output that object.
var input ={
"careerLevel": "Associate",
"careerLevels": [
{
"201609": 21,
"201610": 22,
"201611": 23,
"careerID": "10000120"
},
{
"201609": 31,
"201610": 32,
"201611": 33,
"careerID": "10000130"
}]
};
const out = input.careerLevels.reduce((prev, current) => {
return (prev.careerID > current.careerID) ? prev : current
}, false)
console.log(out);

An alternative is sorting and getting the last object.
var input = { "careerLevel": "Associate", "careerLevels": [{ "201609": 21, "201610": 22, "201611": 23, "careerID": "10000120" }, { "201609": 31, "201610": 32, "201611": 33, "careerID": "10000130" } ]},
highest = input.careerLevels.sort((a, b) => a.careerID - b.careerID).pop();
console.log(highest);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using the function reduce
var input = { "careerLevel": "Associate", "careerLevels": [{ "201609": 21, "201610": 22, "201611": 23, "careerID": "10000120" }, { "201609": 31, "201610": 32, "201611": 33, "careerID": "10000130" } ]},
highest = input.careerLevels.reduce((a, c) => c.careerID > a.careerID ? c : a, {careerID: Number.MIN_SAFE_INTEGER});
console.log(highest);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

How to find all possible paths in 2d array of numbers from the first to the last, where each step's value is greater than the previous step?

The code I've got so far finds only 2 possible paths. How can I rework it to find all of them?
An example of a valid path would be, begin with the first array [1, 32]. Choose a number to step from, like 32.
Look at the next array immediately below: [11, 21, 24, 27, 35, 37, 65]. A valid step would be to any of these numbers that are greater than your current step. So 35, 37, and 65 would all be valid steps.
And continue constructing the path by taking steps onto the other arrays in order (top to bottom) until you reach the last.
'use strict';
const matrix = [
[1, 32],
[11, 21, 24, 27, 35, 37, 65],
[17, 22, 25, 51, 57, 63],
[18, 56]
];
function findPaths(arrays) {
const paths = [];
for (let i = 0; i < arrays[0].length; i++) {
const path = [arrays[0][i]];
for (let j = 1; j < arrays.length; j++) {
for (let y = 0; y < arrays[j].length; y++) {
if (path[Math.max(0, path.length - 1)] < arrays[j][y]) {
path.push(arrays[j][y]);
break;
}
}
}
paths.push(path);
}
return paths;
}
const result = findPaths(matrix);
console.log(result); // [ [ 1, 11, 17, 18 ], [ 32, 35, 51, 56 ] ]
I solved it. It's not the most efficient solution, but I'm working on it.
const data = [
[1, 32],
[11, 21, 24, 27, 35, 37, 65],
[17, 22, 25, 51, 57, 63],
[18, 56]
];
function findPaths(arrays) {
const paths = [];
const maxPaths = arrays.reduce((total, arr) => total *= arr.length || total, 1);
for (let x = 0; x < maxPaths; x++) {
for (let i = 0; i < arrays[0].length; i++) {
const path = [arrays[0][i]];
for (let j = 1; j < arrays.length; j++) {
for (let y = 0; y < arrays[j].length; y++) {
if (path[Math.max(0, path.length - 1)] < arrays[j][y]) {
if (!paths.some(p => p.toString() == [...path, arrays[j][y]].toString())) {
path.push(arrays[j][y]);
break;
}
}
}
}
paths.push(path);
}
}
return paths.filter(path => path.length == arrays.length).sort();
}
const result = findPaths(data);
console.log(result);
/*
[
[ 1, 11, 17, 18 ], [ 1, 11, 17, 56 ],
[ 1, 11, 22, 56 ], [ 1, 11, 25, 56 ],
[ 1, 11, 51, 56 ], [ 1, 21, 22, 56 ],
[ 1, 21, 25, 56 ], [ 1, 21, 51, 56 ],
[ 1, 24, 25, 56 ], [ 1, 24, 51, 56 ],
[ 1, 27, 51, 56 ], [ 1, 35, 51, 56 ],
[ 1, 37, 51, 56 ], [ 32, 35, 51, 56 ],
[ 32, 37, 51, 56 ]
]
*/

How does this for in Loop Work to Sort Numbers using Quick Sort in JavaScript

How does the for in loop work below to correctly sort the numbers in the left array and right array for the quick sort implementation below?
I'd like an example of a first example iteration of the sortArr(left) recursive call, then another iteration, and so on (maybe up to three or four iterations).
Then I'll be able to understand the sortArr(left), including the sortArr(right) recursive call.
const unsortedArr = [31, 27, 28, 42, 13, 8, 11, 30, 17, 41, 15, 43, 1, 36, 9, 16, 20, 35, 48, 37, 7, 26, 34, 21, 22, 6, 29, 32, 49, 10, 12, 19, 24, 38, 5, 14, 44, 40, 3, 50, 46, 25, 18, 33, 47, 4, 45, 39, 23, 2];
let sortArr = (arr) => {
if (arr.length < 2) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
let left = [];
let equal = [];
let right = [];
equal.push(pivot);
for (let element of arr) {
if (element < pivot) {
left.push(element);
} else if (element > pivot) {
right.push(element);
}
}
let sortedArr = sortArr(left)
.concat(equal)
.concat(sortArr(right));
return sortedArr;
};
console.log(sortArr(unsortedArr));

Sorting a JavaScript Object by specific property value

If I have a JavaScript object such as:
var currencies= {
"EUR": 100,
"CHF": 15,
"GPB": 75,
"JPN": 116,
"EUR": 12,
"JPN": 15,
"USD": 55,
"CHF": 22,
"USD": 100,
};
Is there a way to sort them in this specific order?
var currencies= {
"EUR": 12,
"EUR": 100,
"USD": 55,
"USD": 100,
"GPB": 75,
"CHF": 15,
"CHF": 22,
"JPN": 15,
"JPN": 116,
};
By having an array with objects with a single key/value pair, you could take this pair for sorting by key and then by value.
var currencies= [{ EUR: 100 }, { CHF: 15 }, { GPB: 75 }, { JPN: 116 }, { EUR: 12 }, { JPN: 15 }, { USD: 55 }, { CHF: 22 }, { USD: 100 }],
order = { EUR: 1, USD: 2, GBP: 3, CHF: 4, JPN: 5 };
currencies.sort((a, b) => {
var aa = Object.entries(a)[0],
bb = Object.entries(b)[0];
return order[aa[0]] - order[bb[0]] || aa[1] - bb[1];
});
console.log(currencies);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript Json : Sum values by matching json keys

My input in one single json
input = [{
"201609": 0,
"201610": 0,
"201611": 0,
"201804": 130,
"201805": 130,
"fy16Q3": 17,
"fy17Q1": 0,
"fy17": 0,
"fy17Q2": 0,
"fy17Q3": 0
}, {
"201510": 0,
"201610": 0,
"201611": 10,
"201803": 20,
"201804": 30,
"201805": 40,
"201806": 130,
"201809": 130,
"fy17Q1": 2,
"fy17": 3,
"fy17Q2": 5,
"fy17Q3": 6
}];
In the output i want to iterate through all the elements of this json and sum the values of the matching keys. Also keep the non matching lone keys in the output as well.
output =
[{
"201510": 5, // no matching pair
"201609": 3, // no matching pair
"201610": 6+9 = 15, // matching pair exist
"201611": 10+12 = 22,
"201803": 20,
"201804": 30+13 = 33,
"201805": 40+14 = 44,
"201806": 130,
"201809": 130,
"fy16Q3": 17, // no matching pair
"fy17Q1": 2+7 = 9, // matching pair exist
"fy17": 3+8 = 11,
"fy17Q2": 5+9 = 14,
"fy17Q3": 6+100 = 106
}];
The problem is that iam not able to figure out how to handle the keys which don't have a matching pair.
You can try the following code. Your desired output looks different than your logic
var data = input = [{
"201609": 0,
"201610": 0,
"201611": 0,
"201804": 130,
"201805": 130,
"fy16Q3": 17,
"fy17Q1": 0,
"fy17": 0,
"fy17Q2": 0,
"fy17Q3": 0
}, {
"201510": 0,
"201610": 0,
"201611": 10,
"201803": 20,
"201804": 30,
"201805": 40,
"201806": 130,
"201809": 130,
"fy17Q1": 2,
"fy17": 3,
"fy17Q2": 5,
"fy17Q3": 6
}];
var output = data.reduce((arr,d,x) =>{
var keys = Object.keys(d);
keys.forEach( (k) => {
if(!arr[k]) arr[k] = 0;
arr[k] = arr[k] + d[k];
})
return arr;
},{});
console.log(output);
input = [{
"201609": 0,
"201610": 0,
"201611": 0,
"201804": 130,
"201805": 130,
"fy16Q3": 17,
"fy17Q1": 0,
"fy17": 0,
"fy17Q2": 0,
"fy17Q3": 0
}, {
"201510": 0,
"201610": 0,
"201611": 10,
"201803": 20,
"201804": 30,
"201805": 40,
"201806": 130,
"201809": 130,
"fy17Q1": 2,
"fy17": 3,
"fy17Q2": 5,
"fy17Q3": 6
}];
var output = input.reduce((p,c) => {
for(let k in c){
p[k] = (p[k] || 0) + c[k];
}
return p;
},{});
console.log(output);
input = [{
"201609": 0,
"201610": 0,
"201611": 0,
"201804": 130,
"201805": 130,
"fy16Q3": 17,
"fy17Q1": 0,
"fy17": 0,
"fy17Q2": 0,
"fy17Q3": 0
}, {
"201510": 0,
"201610": 0,
"201611": 10,
"201803": 20,
"201804": 30,
"201805": 40,
"201806": 130,
"201809": 130,
"fy17Q1": 2,
"fy17": 3,
"fy17Q2": 5,
"fy17Q3": 6
}];
var output = [{}];
for( i in input){
for (key in input[i]){
if(output[0].hasOwnProperty(key)){
output[0][key]+=input[i][key];
}else{
output[0][key]=input[i][key];
}
}
}
console.log(output)
Use array reduce method. In this method take the first object of the input array as the initial object since.SInce object keys are always unique, for any matching key just update the value
var input = [{
"201609": 0,
"201610": 0,
"201611": 0,
"201804": 130,
"201805": 130,
"fy16Q3": 17,
"fy17Q1": 0,
"fy17": 0,
"fy17Q2": 0,
"fy17Q3": 3
}, {
"201510": 0,
"201610": 0,
"201611": 10,
"201803": 20,
"201804": 30,
"201805": 40,
"201806": 130,
"201809": 130,
"fy17Q1": 2,
"fy17": 3,
"fy17Q2": 5,
"fy17Q3": 6
}];
// the array will start reducing from second element that is
// element from index 1
let toLoopArray = input.slice(1, input.length);
let output = input.reduce(function(acc, curr) {
// for the current object check if the key already exist
// if not then create the new key and update value
for (let keys in curr) {
if (!acc.hasOwnProperty(keys)) {
acc[keys] = curr[keys]
} else {
// acc[keys] = acc[keys] + curr[keys]
console.log(curr[keys])
acc[keys] = acc[keys] + curr[keys]
}
}
return acc;
}, input[0])
console.log([output])

javascript remove duplicates from array of arrays

How to remove duplicates on an array like below:
arr = [
[828, 187, 1, 14, 1, 25, 1417608935730],
[828, 187, 1, 14, 1, 25, 1417608935740],
[828, 187, 1, 14, 1, 25, 1417608935750],
[828, 187, 1, 14, 1, 25, 1417608935760],
[600, 578, 1, 14, 1, 25, 1417608935760],
[828, 187, 1, 14, 1, 25, 1417608935780],
[828, 187, 1, 14, 1, 25, 1417608935790]
]
Since 4th and 5th array have 1417608935760 similar value I want to delete next duplicate and keep only one.
I tried this but not working:
$.each(arr, function(i, insidearr){
if($.inArray(insidearr[6], uniqueNames) === -1)
uniqueNames.push(insidearr);
});
Pls help. Thanks in advance
You're pushing the entire row into uniqueNames. The array will never be equal to the number at the end of each row, so the $.inArray() test will always fail. You need separate arrays for just the element you're comparing and the resulting array.
var newArray = [];
var uniqueNames = {};
$.each(arr, function(i, insidearr) {
if (!(insidearr[6] in uniqueNames)) {
newArray.push(insidearr);
uniqueNames[insidearr[6]] = true;
}
});
I used an object rather than an array for uniqueNames, because searching for an object key is faster than scanning an array.
Just try with:
var uniqueArr = $.grep(arr, function(insidearr){
if ($.inArray(insidearr[6], uniqueNames) === -1) {
uniqueNames.push(insidearr[6]);
return true;
}
});
try this one:
var arr = [
[828, 187, 1, 14, 1, 25, 1417608935730],
[828, 187, 1, 14, 1, 25, 1417608935740],
[828, 187, 1, 14, 1, 25, 1417608935750],
[828, 187, 1, 14, 1, 25, 1417608935760],
[600, 578, 1, 14, 1, 25, 1417608935760],
[828, 187, 1, 14, 1, 25, 1417608935780],
[828, 187, 1, 14, 1, 25, 1417608935790]
];
var len = arr.length;
while(--len) {
if(arr[len][6] == arr[len-1][6]) {
arr.splice(len-1, 1)
}
}
console.log(arr); // here is what you want
If you don't want to manipulate arr, you just need to clone the array by var newArr = arr.slice()

Categories

Resources