I have an object table in which there is the score and the name of a character and I would like to retrieve the index with the highest score to be able to make a scoreboard.
This is what my array looks like
[
{
"score": 51,
"name": "toto"
},
{
"score": 94,
"name": "tata"
},
{
"score": 27,
"name": "titi"
},
{
"score": 100,
"name": "tutu"
}
]
In this case, I would like to get the index of the person who has the highest score, in this case, the index is 3 because it is tutu who has the highest score.
Thank advance for ur help
The sort function should do it:
var raw_scores = [
{
"score": 51,
"name": "toto"
},
{
"score": 94,
"name": "tata"
},
{
"score": 27,
"name": "titi"
},
{
"score": 100,
"name": "tutu"
}
]
var sorted_scores = raw_scores.sort(function(a,b){return b.score - a.score})
More info at w3schools
Using for loop
var index = 0;
var max = 0;
for (var i = 0; i < scores.length; i++) {
if (s[i].score > max) {
max = s[i].score;
index = i;
}
}
console.log(index);
You can use the reduce function
const array = [
{
"score": 51,
"name": "toto"
},
{
"score": 94,
"name": "tata"
},
{
"score": 27,
"name": "titi"
},
{
"score": 100,
"name": "tutu"
}
];
const highestScore = array.reduce((last, item) => {
// return the item if its score is greater than the highest score found.
if(!last || last.score < item.score) {
return item;
}
return last;
});
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
var data = [{
"score": 51,
"name": "toto"
},
{
"score": 94,
"name": "tata"
},
{
"score": 27,
"name": "titi"
},
{
"score": 100,
"name": "tutu"x
}
];
var max_score = Math.max.apply(Math, data.map(function(o) {
return o.score;
}))
console.log(data.filter(i => i.score === max_score))
[...].reduce((acc, item, idx) => (item.score > acc.score ? {score: item.score, index: idx} : acc), {score: 0, index:0}).index
Related
I have an express server which I have GET and POST, and as original state, I have the following:
let orders = [
{
sum: 0,
purchases: [
{
id: 1,
contractId: 55,
value: 100,
},
{
id: 2,
contractId: 55,
value: -100,
}
]
}
]
// this function is running on GET request
export const getOrders = (req, res) => {
reply.status(200).send(orders)
}
export const addOrder = (req, res) => {
const newOrder = req.body
orders.map((order) => {
const correspondingorder = order.purchases.find(
(purshase) => purshase.contractId === newOrder.contractId
)
if (correspondingorder) {
order.purchases.push(newOrder)
order.sum += newOrder.value
} else {
const newValues = { sum: newOrder.value, purchases: Array(newOrder) }
orders.push(newValues)
}
}
}
My intention here is to search in the list of orders if the new added order ID is exist, if so, then add it to the list of corresponding purchases, otherwise, create a new object containing a sum and the new order, but whenever I try to add a new order with the same id then it add it to the found contractID PLUS creating a new object containing a sum and new order.
here is an example of what I get after my first POST and then GET:
[
{
"sum": 100,
"purchases": [
{
"id": 1,
"contractId": 55,
"value": 100
},
{
"id": 2,
"contractId": 55,
"value": -100
},
{
"id": 3,
"contractId": 55,
"value": 100
}
]
}
]
then my second attempts of adding a different order with POST:
[
{
"sum": 100,
"purchases": [
{
"id": 1,
"contractId": 55,
"value": 100
},
{
"id": 2,
"contractId": 55,
"value": -100
},
{
"id": 3,
"contractId": 55,
"value": 100
}
]
},
{
"sum": 100,
"purchases": [
{
"id": 3,
"contractId": 44,
"value": 100
}
]
}
]
then another post and got this results:
[
{
"sum": 100,
"purchases": [
{
"id": 1,
"contractId": 55,
"value": 100
},
{
"id": 2,
"contractId": 55,
"value": -100
},
{
"id": 3,
"contractId": 55,
"value": 100
}
]
},
{
"sum": 200,
"purchases": [
{
"id": 3,
"contractId": 44,
"value": 100
},
{
"id": 4,
"contractId": 44,
"value": 100
}
]
},
{
"sum": 100,
"purchases": [
{
"id": 4,
"contractId": 44,
"value": 100
}
]
}
]
any idea why this weird behavior is happening?
This is because orders.map returns a new object and doesn't mutate the original, you can override the original with:
orders = orders.map((order) => {
const correspondingorder = order.purchases.find(
(purshase) => purshase.contractId === newOrder.contractId
)
if (correspondingorder) {
order.purchases.push(newOrder)
order.sum += newOrder.value
} else {
const newValues = { sum: newOrder.value, purchases: Array(newOrder) }
orders.push(newValues)
}
}
}
But honestly, I don't recommend mutating Objects in this context, because more than 1 request can be reading/writing that variable.
If you really need to use this approach, use Array.forEach and reference the original object instead of map (that returns a new array and doesn't mutate the original one)
I need to get the parent id of the specific child.
Here is my sample JSON, If I give entity id 32 it should return 6 as parent Id and if I give 30 it should return 5 as parent id.
const arr = [{
"id": 0,
"name": "My Entity",
"children": [
{
"id": 1,
"name": "MARKET",
"children": [
{
"id": 2,
"name": "Sales",
"children": [
{
"id": 3,
"name": "District 1",
"children": [
{
"id": 5,
"name": "Area 1",
"children": [
{
"entityId": 30,
"id": 26,
"name": "Mumbai"
},
{
"entityId": 31,
"id": 26,
"name": "Hyderabad"
}
],
"num": 0,
},
{
"id": 6,
"name": "Area 2",
"children": [
{
"entityId": 32,
"id": 32,
"name": "Karnataka"
},
{
"entityId": 33,
"id": 33,
"name": "Andhra Pradesh"
}
],
"num": 0,
},
]
},
]
},
]
},
]
}]
Here is the code I have tried
const findParent = (arr, entityId) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].entityId === entityId) {
return [];
} else if (arr[i].children && arr[i].children.length) {
const t = findParents(arr[i].children, entityId);
if (t !== false) {
t.push(arr[i].id);
return t;
}
}
}
return false;
};
findParents(arr, 30);
But it is returning like below
[
5,
3,
2,
1,
0
]
But I want the output to be
[
5
]
Kindly help me on this, thanks
Replace this:
t.push(arr[i].id);
with:
if (t.length == 0) t.push(arr[i].id);
I would suggest easier solution
const findParent = (arr, entityId) => {
const children = arr.flatMap(parent =>
(item.children || []).map(child => ({ parent, child, entityId: child.entityId }))
)
const res = children.find(item => item.entityId === entityId)
return res.entityId || findChildren(res.map(v => v.child), entityId)
}
I have an array of objects like below:
[
{
"id": 100,
"Name": "T1",
"amt": 15,
},
{
"id": 102,
"Name": "T3",
"amt": 15,
},
{
"id": 100,
"Name": "T1",
"amt": 20,
},
{
"id": 105,
"Name": "T6",
"amt": 15,
}
]
I want to filter the objects in the array by the minimum of amt. There are two objects with id's 100 but different amt (15 and 20). I want to filter the minimum value which is 15. The output should be:
[
{
"id": 100,
"Name": "T1",
"amt": 15,
},
{
"id": 102,
"Name": "T3",
"amt": 15,
},
{
"id": 105,
"Name": "T6",
"amt": 15,
}
]
I followed this post but does not fit with my problem.
Is there any simpler way of doing this, either pure JavaScript or lodash?
You could group by id and take from every group the object with min value of amt.
var data = [{ id: 100, Name: "T1", amt: 15 }, { id: 102, Name: "T3", amt: 15 }, { id: 100, Name: "T1", amt: 20 }, { id: 105, Name: "T6", amt: 15 }],
result = _(data)
.groupBy('id')
.map(group => _.minBy(group, 'amt'))
.value();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Use the standard algorithm for finding min value and apply the approach to the reduce function. When you find the min or the equal value to the min, add the current object to the array.
const arr = [{
"id": 100,
"Name": "T1",
"amt": 15,
},
{
"id": 102,
"Name": "T3",
"amt": 15,
},
{
"id": 100,
"Name": "T1",
"amt": 20,
},
{
"id": 105,
"Name": "T6",
"amt": 15,
}
]
const minArr = arr.reduce((acc, curr) => curr.amt <= acc.min ? {
...acc,
min: curr.amt,
arr: [...acc.arr, curr]
} : acc, {
min: Infinity,
arr: []
}).arr
console.log(minArr);
You can do this using a for loop like so:
var minimum = 5;
for(var i = 0; i < yourArray; i++) {
if(yourArray[i].amt < minimum) {
console.log("The " + i + " item in the array's amount is less than the minimum: " + minimum);
}
}
Or you can use Array.filter:
var minimum = 5;
function isBigEnough(value) {
return value >= minimum
}
someArray.filter(isBigEnough)
This question already has answers here:
How to filter object array based on attributes?
(21 answers)
Closed 6 years ago.
Can I filter or extract the values of an object, based on a value?
For example [10, 19] would return Bill and Sam.
[ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
Thanks/
You can chain filter then map functions :
const mySearch = [10, 19]
const result = myArray.filter(elem => mySearch.indexOf(elem.id) > -1) // filter by id
.map(elem => elem.nice_name) // return the nice_name only for each entry
// result is now ['Bill', 'Sam']
You can use Array.prototype.filter() function:
const data = [ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
const result = data.filter(o => ~[10, 19].indexOf(o.id))
// ~[10, 19].indexOf(o.id) is equivalent to [10, 19].indexOf(o.id) > -1
Using only javascript you can do something like this.
var size = a.length; //a -> your array
var inputSize = input.length; // -> the search array
var thePeople = []; //where you will store the names that match
for(var i = 0; i < size; i++) { //cycle your array
for(var j = 0; j < inputSize; j++) { //cycle the search array
if(a[i].id === input[j]) { //check if there is a match on id
thePeople.push(a[i].nice_name); //save the name into a new array
}
}
}
here is a fiddle https://jsfiddle.net/xo5vxwo0/
indexOf to find an element in array .
arr=[ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
var fill=[10,19];
var ans=[];
arr.map(function(a){
if(fill.indexOf(a["id"])>-1)
ans.push(a["nice_name"]);
})
console.log(ans);
*{
background-color:pink;
}
var data = [ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
var idWant = [10,19];
var content = '';
for(var keysWant in idWant){
var number = idWant[keysWant];
for(var keysData in data){
if(number == data[keysData]['id']){
content += data[keysData]['nice_name'] + ' ';
}
}
}
console.log(content);
One might use a single reduce instead of filter.map chain.
var arr = [ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
],
src = [10,19],
result = arr.reduce((r,o) => src.includes(o.id ) ? r.concat(o.nice_name) : r,[]);
console.log(result);
I have an array of objects that looks like this
[{
"name": "Agile Process",
"id": 27,
"score": 3,
"source": "Self"
},{
"name": "Agile Process",
"id": 27,
"score": 4,
"source": "Trainer"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 4,
"source": "Self"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 5,
"source": "Trainer"
}]
I want to be able to produce something like this, I have been trying hard but I do not seems to get a hang of it.
[
{
"name": "Agile Process",
"id": 7,
"data": [
{
"score": 3,
"source": "Self"
},{
"score": 4,
"source": "Trainer"
}
]
},
{
"name": "2 & 3 Tier Architecture",
"id": 37,
"data": [
{
"score": 4,
"source": "Self"
},{
"score": 5,
"source": "Trainer"
}]
}
];
How do I go about solving this problem?
One possible approach:
_.values(_.reduce(arr, function(acc, el) {
var id = el.id;
if (!acc.hasOwnProperty(id)) {
acc[id] = _.pick(el, 'id', 'name');
acc[id].data = [];
}
acc[id].data.push(_.pick(el, 'score', 'source'));
return acc;
}, {}));
Demo. It's a common method when you need to group things up.
Here's a pure javascript solution: use reduce method on the initial array using as the accumulator the result array (empty at first) which will store the transformed data. And as reduce method loops through the items of the initial array, check if the result array contains an element with id of the current item. If so, then just add new data to it, else create a new item in the result array.
var data = [{
"name": "Agile Process",
"id": 27,
"score": 3,
"source": "Self"
},{
"name": "Agile Process",
"id": 27,
"score": 4,
"source": "Trainer"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 4,
"source": "Self"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 5,
"source": "Trainer"
}];
var newData = [];
newData = data.reduce(function(acc, current) {
var existingArr = acc.filter(function(x) { return x.id === current.id });
if(existingArr.length === 0) {
acc.push({ name: current.name, id: current.id, data: [{ score: current.score, source: current.source }] });
}
else {
existingArr[0].data.push({ score: current.score, source: current.source });
}
return acc;
}, newData);
This version uses groupBy to group the items by id and then maps across each grouping to create the required object:
var groupToItem = function(items){
return {
id: items[0].id,
name: items[0].name,
data: _.map(items, function(item){
return _.pick(item, 'score', 'source');
})
}
}
var result = _.chain(data)
.groupBy('id')
.map(groupToItem)
.value();
Plain Javascript solution, only working for your specific data structure though:
function groupObjectsById(array){
var output = [];
var ids = [];
for(var i = 0; i < array.length; i++){
var current = array[i];
if(ids.indexOf(current.id) > -1){
var objInOutput = output.filter(function(obj){
if(obj.id === current.id){
return obj;
}
})[0];
var dataObj = { score: current.score, source: current.source};
objInOutput.data.push(dataObj);
}else{
var outputObject = {name: current.name, id: current.id};
outputObject.data = [{ score: current.score, source: current.source}];
output.push(outputObject);
ids.push(current.id);
}
}
return output;
}