How to find user_value closest value from this array?
Here is user_value variable according to this i need find out closest value from array.
var user_value = 5500;
var array = [
{_id: 5809e269d60f577ae35f6add,
coins: 1000,
is_active: 1,
iconId: 4 },
{_id: 5809e269d60f577ae35f6ade,
coins: 2000,
is_active: 1,
iconId: 5 },
{_id: 5809e269d60f577ae35f6adf,
coins: 5000,
is_active: 1,
iconId: 6 },
{_id: 5809e269d60f577ae35f6ae0,
coins: 7000,
is_active: 1,
iconId: 7 },
{_id: 5809e269d60f577ae35f6ae1,
coins: 10000,
is_active: 1,
iconId: 8 },
{_id: 5809e269d60f577ae35f6ae2,
coins: 15000,
is_active: 1,
iconId: 9 } ];
You could use an iterative approach by using the absolute difference for checking.
var value = 5500,
array = [{ _id: '5809e269d60f577ae35f6add', coins: 1000, is_active: 1, iconId: 4 }, { _id: '5809e269d60f577ae35f6ade', coins: 2000, is_active: 1, iconId: 5 }, { _id: '5809e269d60f577ae35f6adf', coins: 5000, is_active: 1, iconId: 6 }, { _id: '5809e269d60f577ae35f6ae0', coins: 7000, is_active: 1, iconId: 7 }, { _id: '5809e269d60f577ae35f6ae1', coins: 10000, is_active: 1, iconId: 8 }, { _id: '5809e269d60f577ae35f6ae2', coins: 15000, is_active: 1, iconId: 9 }],
result = array.reduce(function (r, a, i, aa) {
return i && Math.abs(aa[r].coins - value) < Math.abs(a.coins - value) ? r : i;
}, -1);
console.log(result);
Assuming you define the closest as Math.abs(array[i].coins - value);, you just need to iterate the array like below:
var user_value = 5500;
var array = [
{
coins: 1000,
is_active: 1,
iconId: 4
},
{
coins: 2000,
is_active: 1,
iconId: 5
},
{
coins: 5000,
is_active: 1,
iconId: 6
},
{
coins: 7000,
is_active: 1,
iconId: 7
},
{
coins: 10000,
is_active: 1,
iconId: 8
},
{
coins: 15000,
is_active: 1,
iconId: 9
}
];
function findClosest (value) {
// By default that will be a big number
var closestValue = Infinity;
// We will store the index of the element
var closestIndex = -1;
for (var i = 0; i < array.length; ++i) {
var diff = Math.abs(array[i].coins - value);
if (diff < closestValue) {
closestValue = diff;
closestIndex = i;
}
}
return closestIndex;
}
console.log("The closest index: " + findClosest(user_value));
var _ = require('underscore');
var user_value = 5500;
var array = [
{ _id: '5809e269d60f577ae35f6add',
coins: 1000,
is_active: 1,
iconId: 4 },
{ _id: '5809e269d60f577ae35f6ade',
coins: 2000,
is_active: 1,
iconId: 5 },
{ _id: '5809e269d60f577ae35f6adf',
coins: 5000,
is_active: 1,
iconId: 6 },
{ _id: '5809e269d60f577ae35f6ae0',
coins: 7000,
is_active: 1,
iconId: 7 },
{ _id: '5809e269d60f577ae35f6ae1',
coins: 10000,
is_active: 1,
iconId: 8 },
{ _id: '5809e269d60f577ae35f6ae2',
coins: 15000,
is_active: 1,
iconId: 9 } ];
function getClosest(array, target) {
var tuples = _.map(array, function(json) {
return [json, Math.abs(json.coins - target)];
});
//console.log(tuples);
return _.reduce(tuples, function(memo, val) {
return (memo[1] < val[1]) ? memo : val;
}, [-1, 999])[0];
}
console.log(getClosest(array, user_value))
Related
I have a case in my react app in which I have to check if values of object in array are the same in sequence and their other property increases squentialy by 1, and then if criteria is fulfilled push it to the new array. Number of values in sequence is provided from input.
For example user wants to push 4 objects to a new array that have their "status": true
objects = [
{
"someID": 0,
"status": false,
},
{
"someID": 1,
"status": false,
},
{
"someID": 2,
"status": true,
},
{
"someID": 3,
"status": true,
},
{
"someID": 4,
"status": true,
},
{
"someID": 6,
"status": true,
},
{
"someID": 7,
"status": false,
},
{
"someID": 8,
"status": false,
},
{
"someID": 9,
"status": true,
},
{
"someID": 10,
"status": true,
},
{
"someID": 11,
"status": true,
},
{
"someID": 12,
"status": true,
},
]
from my example objects with someID 2, 3, 4, 6, fulfill the criteria to have status: true but their someID values do not increase sequentially by 1 on the other hand those objects with someID 9, 10, 11, 12 have their status value as true and their someID values increase sequentially by 1. So the outcome should be
newArray = [
{
"someID": 9,
"status": true,
},
{
"someID": 10,
"status": true,
},
{
"someID": 11,
"status": true,
},
{
"someID": 12,
"status": true,
},
]
below a generic function that takes your array and iterates through a for loop. you pass down the property and expected matched value, just like the exact count in sequence expected:
const getSequence = (arr, count, key = 'status', value = true, id = 'someID') => {
let match = []
const isIDIncremental = (obj) => {
if(match.length === 0) return true
return obj[id] - 1 === match[match.length - 1][id]
}
for(const obj of arr) {
if(match.length === count) break
if(obj[key] === value && isIDIncremental(obj)) {
match.push(obj)
} else {
match = []
}
}
return match.length === count ? match : []
}
You could check status and the predecessor or successor.
const
objects = [{ someID: 0, status: true }, { someID: 1, status: false }, { someID: 2, status: true }, { someID: 3, status: true }, { someID: 4, status: true }, { someID: 5, status: false }, { someID: 6, status: false }, { someID: 7, status: true }],
result = objects.filter(({ someID, status }, i, a) => status && (
a[i - 1]?.status && a[i - 1]?.someID === someID - 1 ||
a[i + 1]?.status && someID + 1 === a[i + 1]?.someID
));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I Have created a Schema to store user Details and Some information regarding it's test.
const mongoose = require("mongoose");
const schema = mongoose.Schema;
const userSchema = new schema({
name: { type: String },
gender: { type: String },
stream: { type: String },
email: {
type: String,
required: true,
unique: true,
match: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/,
},
verified: { type: Boolean, default: false },
password: { type: String, required: true },
// For premium Calculations
test: {
type1Count: { type: Number, default: 0 },
type2Count: { type: Number, default: 0 },
type3Count: { type: Number, default: 0 },
},
testCompleted: [
{
testId: { type: Number },
testDate: { type: Number },
testTypeNumber: { type: Number },
testTypeName: { type: String },
testDurationInMinutes: {type: Number},
listOfQuestionId: [{ type: String }],
listOfCorrectAnswer: [{ type: Number }],
listOfAnswerByUser: [{ type: Number }],
totalNumberOfQuestion: { type: Number, default: 0 },
numberOfAttemptedQuestion: { type: Number, default: 0 },
numberOfUnattemptedQuestion: { type: Number, default: 0 },
numberOfCorrectAnswer: { type: Number, default: 0 },
numberOfWrongAnswer: { type: Number, default: 0 },
marksObtained: {type: Number, default: 0 },
isTestCompleted : {type: Boolean, default: false}
},
]
});
module.exports = mongoose.model("User", userSchema);
Now, I am able to save half Data in the testCompletd array from this code ...
User.findOneAndUpdate(
{ _id: user._id}, // for Verification
{ $push:
{ testCompleted:
{
testId: Object.keys(user.testCompleted).length +1, // I choose Normal serialise Number starting from 1
testDate: Date.now(),
testTypeNumber: type,
testTypeName: testList[type - 1]["testName"],
testDurationInMinutes: testList[type - 1]["testDurationInMinutes"],
weightageOfQuestion: list[type - 1],
totalNumberOfQuestion: list[type - 1]["physics"] + list[type - 1]["chemistry"] + list[type - 1]["biology"],
listOfQuestionId: arrayOfQuestion,
listOfCorrectAnswer: arrayOfAnswer
}
}
}
)
Now, this will result a multiple insertions of data in the database like this ...when i hit the Routes 2 times...and That's work fine..
{
"_id" : ObjectId("5f436c5bf183fb93266a5574"),
"test" : {
"type1Count" : 0,
"type2Count" : 0,
"type3Count" : 0
},
"verified" : false,
"name" : "prince",
"email" : "kumar#gmail.com",
"password" : "$2a$10$RCVA2YNzKPjTJKDJhCfeZuqw83GnruQ4s9/7EhrkOs4JpuUVG2j9C",
"testCompleted" : [
{
"listOfQuestionId" : [
"5f3fc58aec2c8d59e5258625",
"5f3fc591ec2c8d59e5258636",
"5f3fc58cec2c8d59e525862a",
"5f3fc593ec2c8d59e525863a",
"5f3fc57bec2c8d59e5258617",
"5f3fc588ec2c8d59e5258622",
"5f3fc57cec2c8d59e5258619",
"5f3fc58aec2c8d59e5258626",
"5f3fc588ec2c8d59e5258621",
"5f3fc57dec2c8d59e525861a",
"5f3fc55cec2c8d59e52585f4",
"5f3fc56cec2c8d59e525860d",
"5f3fc55aec2c8d59e52585f1",
"5f3fc561ec2c8d59e52585fa",
"5f3fc568ec2c8d59e5258607",
"5f3fc55bec2c8d59e52585f2",
"5f3fc570ec2c8d59e5258614",
"5f3fc56fec2c8d59e5258612",
"5f3fc565ec2c8d59e5258601",
"5f3fc566ec2c8d59e5258603",
"5f3fc526ec2c8d59e52585a4",
"5f3fc545ec2c8d59e52585d2",
"5f3fc54dec2c8d59e52585e1",
"5f3fc54cec2c8d59e52585e0",
"5f3fc53fec2c8d59e52585c6",
"5f3fc549ec2c8d59e52585d9",
"5f3fc52eec2c8d59e52585ae",
"5f3fc52fec2c8d59e52585af",
"5f3fc554ec2c8d59e52585ed",
"5f3fc53bec2c8d59e52585c0",
"5f3fc52bec2c8d59e52585ac",
"5f3fc52eec2c8d59e52585ad",
"5f3fc542ec2c8d59e52585cb",
"5f3fc527ec2c8d59e52585a5",
"5f3fc54eec2c8d59e52585e3",
"5f3fc536ec2c8d59e52585b9",
"5f3fc546ec2c8d59e52585d4",
"5f3fc53dec2c8d59e52585c3",
"5f3141ed72d27d9df229dfe9",
"5f3fc54dec2c8d59e52585e2"
],
"listOfCorrectAnswer" : [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
4,
1
],
"listOfAnswerByUser" : [],
"totalNumberOfQuestion" : 40,
"numberOfAttemptedQuestion" : 0,
"numberOfUnattemptedQuestion" : 0,
"numberOfCorrectAnswer" : 0,
"numberOfWrongAnswer" : 0,
"marksObtained" : 0,
"isTestCompleted" : false,
"_id" : ObjectId("5f436c6ef183fb93266a5575"),
"testId" : 1,
"testDate" : 1598254190194.0,
"testTypeNumber" : 1,
"testTypeName" : "Minor",
"testDurationInMinutes" : 30
},
{
"listOfQuestionId" : [
"5f3fc58dec2c8d59e525862b",
"5f3fc586ec2c8d59e525861f",
"5f3fc58bec2c8d59e5258628",
"5f3fc58dec2c8d59e525862c",
"5f3fc58aec2c8d59e5258626",
"5f3fc592ec2c8d59e5258638",
"5f3fc591ec2c8d59e5258634",
"5f3fc590ec2c8d59e5258633",
"5f3fc591ec2c8d59e5258636",
"5f3fc58fec2c8d59e5258630",
"5f3fc562ec2c8d59e52585fd",
"5f3fc55eec2c8d59e52585f7",
"5f3fc565ec2c8d59e5258602",
"5f3fc570ec2c8d59e5258614",
"5f3fc571ec2c8d59e5258615",
"5f3fc55cec2c8d59e52585f3",
"5f3fc55aec2c8d59e52585f0",
"5f3fc56fec2c8d59e5258613",
"5f3fc55bec2c8d59e52585f2",
"5f3fc56eec2c8d59e5258611",
"5f3fc54eec2c8d59e52585e3",
"5f3fc549ec2c8d59e52585da",
"5f3fc53eec2c8d59e52585c5",
"5f3fc521ec2c8d59e52585a0",
"5f3fc53dec2c8d59e52585c3",
"5f3fc528ec2c8d59e52585a6",
"5f3fc538ec2c8d59e52585bc",
"5f3fc542ec2c8d59e52585cb",
"5f3fc528ec2c8d59e52585a7",
"5f3fc53cec2c8d59e52585c1",
"5f3fc543ec2c8d59e52585cd",
"5f3fc552ec2c8d59e52585eb",
"5f3fc543ec2c8d59e52585ce",
"5f3fc534ec2c8d59e52585b5",
"5f3fc53cec2c8d59e52585c2",
"5f3fc54cec2c8d59e52585df",
"5f3fc541ec2c8d59e52585ca",
"5f3fc542ec2c8d59e52585cc",
"5f3fc548ec2c8d59e52585d7",
"5f3fc549ec2c8d59e52585d9"
],
"listOfCorrectAnswer" : [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"listOfAnswerByUser" : [],
"totalNumberOfQuestion" : 40,
"numberOfAttemptedQuestion" : 0,
"numberOfUnattemptedQuestion" : 0,
"numberOfCorrectAnswer" : 0,
"numberOfWrongAnswer" : 0,
"marksObtained" : 0,
"isTestCompleted" : false,
"_id" : ObjectId("5f436c7bf183fb93266a5576"),
"testId" : 2,
"testDate" : 1598254203550.0,
"testTypeNumber" : 1,
"testTypeName" : "Minor",
"testDurationInMinutes" : 30
}
],
"__v" : 0
}
Now, as you can see that, In my user model I have others field also in my testCompleted Section...like ..
listOfAnswerByUser: listOfAnswerByUser,
totalNumberOfQuestion: totalNumberOfQuestion,
numberOfAttemptedQuestion: attempt,
numberOfUnattemptedQuestion: totalNumberOfQuestion - attempt,
numberOfCorrectAnswer: attempt - wrong,
numberOfWrongAnswer: wrong,
marksObtained: marks,
isTestCompleted: true
Now, I want to save these data in a particular index of that array but it doesn't work please help me ...
I am trying like this but IT DOESN'T WORK.
User.findOneAndUpdate(
{ _id: user._id, "testCompleted.testId": 0}, // for Verification // 5f42cd4cf3a7458ddd4f5013
{ $push:
{ testCompleted:
{
testId: testId,
listOfAnswerByUser: listOfAnswerByUser,
totalNumberOfQuestion: totalNumberOfQuestion,
numberOfAttemptedQuestion: attempt,
numberOfUnattemptedQuestion: totalNumberOfQuestion - attempt,
numberOfCorrectAnswer: attempt - wrong,
numberOfWrongAnswer: wrong,
marksObtained: marks,
isTestCompleted: true
}
}
}
)
In order to update an array-element at a specific index, you can use the positional-operator in combination with $set:
User.findOneAndUpdate(
{_id: user._id, "testCompleted.testId": "<testId you want to update>"},
{
$set: {
"testCompleted.$": {
numberOfAttemptedQuestion: attempt,
numberOfUnattemptedQuestion: totalNumberOfQuestion - attempt,
numberOfCorrectAnswer: attempt - wrong,
numberOfWrongAnswer: wrong,
marksObtained: marks,
isTestCompleted: true
}
}
}
)
I have array like this:
const array = [{
id: 1,
date: 591020824000,
isImportant: false,
},
{
id: 2,
date: 591080224000,
isImportant: false,
},
{
id: 3,
date: 591080424000,
isImportant: true,
},
{
id: 4,
date: 591080225525,
isImportant: false,
},
{
id: 5,
date: 591020225525,
isImportant: true,
},
];
And I'm trying to sort this array so elements that are isImportant: true with the most recent date are displayed first and then elements that have isImportant:false with the most recent date
array.sort(function(a,b){
if(a.isImportant && !b.isImportant)
return -1;
if(!a.isImportant && b.isImportant)
return 1;
return b.date-a.date;
});
I hope this will resolve your issue
array.sort((a,b)=>{
if(a.isImportant==b.isImportant){
return b.date-a.date;
}else{
return a.isImportant?-1:1;
}
})
duplicate of this
I have a requirement to group an array of objects based on time interval. The input looks like:
[
{
_id: {
hour: 0,
interval: '0'
},
time: '0:0',
count: 10
},
{
_id: {
hour: 0,
interval: '15'
},
time: '0:15',
count: 5
},
{
_id: {
hour: 0,
interval: '30'
},
time: '0:30',
count: 1
},
{
_id: {
hour: 0,
interval: '45'
},
time: '0:45',
count: 2
},
{
_id: {
hour: 1,
interval: '0'
},
time: '1:0',
count: 4
},
{
_id: {
hour: 1,
interval: '15'
},
time: '1:15',
count: 3
},
{
_id: {
hour: 1,
interval: '30'
},
time: '1:30',
count: 5
},
{
_id: {
hour: 1,
interval: '45'
},
time: '1:45',
count: 1
}
]
My desired output:
[
{
"time": "0",
"0": 10,
"15": 5
"30": 1,
"45": 2
},
{
"time": "1",
"0": 4,
"15": 3
"30": 5,
"45": 1
}
]
I tried to use the following code to group the objects, which works to an extent, but I'm stuck on what to do next:
const a = [ { _id: { hour: 0, interval: '0' }, time: '0:0', count: 10 }, { _id: { hour: 0, interval: '15' }, time: '0:15', count: 5 }, { _id: { hour: 0, interval: '30' }, time: '0:30', count: 1 }, { _id: { hour: 0, interval: '45' }, time: '0:45', count: 2 }, { _id: { hour: 1, interval: '0' }, time: '1:0', count: 4 }, { _id: { hour: 1, interval: '15' }, time: '1:15', count: 3 }, { _id: { hour: 1, interval: '30' }, time: '1:30', count: 5 }, { _id: { hour: 1, interval: '45' }, time: '1:45', count: 1 }]
var group = a.reduce((r, a) => {
console.log("a", a);
console.log('r', r);
r[a._id.hour] = [...r[a._id.hour] || [], a];
return r;
}, {});
console.log("group", group);
Check if the object with that hour exists in the accumulator object first - if it doesn't, create one, then assign count to that object's [interval] property, and get the Object.values at the end to turn it back into an array:
const input=[{_id:{hour:0,interval:"0"},time:"0:0",count:10},{_id:{hour:0,interval:"15"},time:"0:15",count:5},{_id:{hour:0,interval:"30"},time:"0:30",count:1},{_id:{hour:0,interval:"45"},time:"0:45",count:2},{_id:{hour:1,interval:"0"},time:"1:0",count:4},{_id:{hour:1,interval:"15"},time:"1:15",count:3},{_id:{hour:1,interval:"30"},time:"1:30",count:5},{_id:{hour:1,interval:"45"},time:"1:45",count:1}];
const groupedObj = {};
for (const { _id: { hour, interval }, count } of input) {
if (!groupedObj[hour]) {
groupedObj[hour] = { time: hour };
}
groupedObj[hour][interval] = count;
}
const output = Object.values(groupedObj);
console.log(output);
Reduce the array, and create an object for each _id.time. Assign the current [interval] = count to the object. Get the entries, and use Array.from() to convert the entries to an array of the required form:
const arr = [{"_id":{"hour":0,"interval":"0"},"time":"0:0","count":10},{"_id":{"hour":0,"interval":"15"},"time":"0:15","count":5},{"_id":{"hour":0,"interval":"30"},"time":"0:30","count":1},{"_id":{"hour":0,"interval":"45"},"time":"0:45","count":2},{"_id":{"hour":1,"interval":"0"},"time":"1:0","count":4},{"_id":{"hour":1,"interval":"15"},"time":"1:15","count":3},{"_id":{"hour":1,"interval":"30"},"time":"1:30","count":5},{"_id":{"hour":1,"interval":"45"},"time":"1:45","count":1}];
// convert the entries to an array
const result = Array.from(Object.entries(
arr.reduce((r, o) => {
const { hour, interval } = o._id; // get the hour and interval
if(!r[hour]) r[hour] = {}; // create a the hour object
r[hour][interval] = o.count; // add the interval and count
return r;
}, {})
), ([time, values]) => ({ time, ...values })); // generate the result objects
console.log(result)
You can group object by reduce method. So at first you need to group by hour and then just add interval properties from each iteration of reduce method to the hour property:
const result = arr.reduce((a, c) => {
a[c._id.hour] = a[c._id.hour] || {};
a[c._id.hour].time = c._id.hour;
a[c._id.hour][c._id.interval] = c.count;
return a;
}, {})
console.log(result);
An example:
let arr = [
{
_id: {
hour: 0,
interval: '0'
},
time: '0:0',
count: 10
},
{
_id: {
hour: 0,
interval: '15'
},
time: '0:15',
count: 5
},
{
_id: {
hour: 0,
interval: '30'
},
time: '0:30',
count: 1
},
{
_id: {
hour: 0,
interval: '45'
},
time: '0:45',
count: 2
},
{
_id: {
hour: 1,
interval: '0'
},
time: '1:0',
count: 4
},
{
_id: {
hour: 1,
interval: '15'
},
time: '1:15',
count: 3
},
{
_id: {
hour: 1,
interval: '30'
},
time: '1:30',
count: 5
},
{
_id: {
hour: 1,
interval: '45'
},
time: '1:45',
count: 1
}
]
const result = arr.reduce((a, c) => {
a[c._id.hour] = a[c._id.hour] || {};
a[c._id.hour].time = c._id.hour;
a[c._id.hour][c._id.interval] = c.count;
return a;
}, {})
console.log(result);
There are two arrays of objects, a and b. Key is 'id' ,'isfix' ,'groupid'.
For example
a.id === b.id && a.isfix === b.isfix && a.groupid===b.groupdid
The sequence array is not the same.
I expected c.
I hope you don't use lodash. I like es6 or vanila js. thanks..
I think reduce and map and filter.. but Not as well as I thought.
I think make function...
input is a,b and output is c
var a = [
{
id:"555",
groupID:"10",
isFix:false,
tolerancePlus:5,
toleranceMinus:3
},
{
id:"123",
groupID:"10",
isFix:true,
tolerancePlus:"",
toleranceMinus:7
},
{
id:"555",
groupID:"10",
isFix:true,
tolerancePlus:11,
toleranceMinus:6
}
]
var b = [
{
id:"123",
groupID:"10",
isFix:true,
tolerance:{
min: null,
plus : null
}
},
{
id:"555",
groupID:"10",
isFix:false,
tolerance:{
min: null,
plus : null
}
},
{
id:"555",
groupID:"10",
isFix:true,
tolerance:{
min: null,
plus : null
}
},
]
var c = [
{
id:"123",
groupID:"10",
isFix:true,
tolerance:{
min: 7,
plus : 0 // if "" that value is 0
}
},
{
id:"555",
groupID:"10",
isFix:false,
tolerance:{
min: 3,
plus : 5
}
},
{
id:"555",
groupID:"10",
isFix:true,
tolerance:{
min: 6,
plus : 11
}
},
]
here's a way to do it :
it uses :
Array.reduce
Array.push
the ~ (bitwise not) operator
disclaimer : since it uses the ~ operator, it can (and will) break if your tolerance are not 32-bit integers (it's undefined behavior AFAIR)
// create your arrays
var a = [{id:"555",groupID:"10",isFix:false,tolerancePlus:5,toleranceMinus:3},{id:"123",groupID:"10",isFix:true,tolerancePlus:"",toleranceMinus:7},{id:"555",groupID:"10",isFix:true,tolerancePlus:11,toleranceMinus:6}]
var b = [{id:"123",groupID:"10",isFix:true,tolerance:{min: null,plus : null}},{id:"555",groupID:"10",isFix:false,tolerance:{min: null,plus : null}},{id:"555",groupID:"10",isFix:true,tolerance:{min: null,plus : null}},]
// loop over b, creating a new array
let c = b.reduce((acc, value) => {
// find an object from a which correspond to the current object
let linked = a.find(val => val.id === value.id && value.groupID === val.groupID && val.isFix === value.isFix)
// if it exists push it in the new array
if(linked) {
acc.push({
id: linked.id,
groupID: linked.groupID,
isFix: linked.isFix,
tolerance:{
min: ~~linked.toleranceMinus, // the ~~value here use some magic to transform
plus : ~~linked.tolerancePlus // everything that's not a number to 0
}
})
}
return acc
}, [])
console.log(c)
var wantedC = [{id:"123",groupID:"10",isFix:true,tolerance:{min: 7,plus : 0}},{id:"555",groupID:"10",isFix:false,tolerance:{min: 3,plus : 5}},{id:"555",groupID:"10",isFix:true,tolerance:{min: 6,plus : 11}}]
console.log(JSON.stringify(wantedC) === JSON.stringify(c))
Here is the Logic in vanilla JS:
var a = [
{
id: '555',
groupID: '10',
isFix: false,
tolerancePlus: 5,
toleranceMinus: 3
},
{
id: '123',
groupID: '10',
isFix: true,
tolerancePlus: '',
toleranceMinus: 7
},
{
id: '555',
groupID: '10',
isFix: true,
tolerancePlus: 11,
toleranceMinus: 6
}
]
var b = [
{
id: '123',
groupID: '10',
isFix: true,
tolerance: {
min: null,
plus: null
}
},
{
id: '555',
groupID: '10',
isFix: false,
tolerance: {
min: null,
plus: null
}
},
{
id: '555',
groupID: '10',
isFix: true,
tolerance: {
min: null,
plus: null
}
}
]
var c = a.map(data1 => {
const toleranceData = b.map(data2 => {
if (
data1.id === data2.id &&
data1.isfix === data2.isfix &&
data1.groupdid === data2.groupdid
) {
return {
tolerance: {
min: data1.toleranceMinus || 0,
plus: data1.tolerancePlus || 0
}
}
}
})
const { tolerance } = toleranceData.filter(d => d)[0]
const { id, groupID, isFix } = data1
return { id, groupID, isFix, tolerance }
})
console.log(c)
So we have 2 arrays of objects:
And we have a statement a.id === b.id && a.isFix === b.isFix && a.groupid===b.groupdid
To get what you need you can use arr.find() inside a arr.map() method and make our changes:
const a = [{ id: "555", groupID: "10", isFix: false, tolerancePlus: 5, toleranceMinus: 3 }, { id: "123", groupID: "10", isFix: true, tolerancePlus: "", toleranceMinus: 7 }, { id: "555", groupID: "10", isFix: true, tolerancePlus: 11, toleranceMinus: 6 } ]
const b = [{ id: "123", groupID: "10", isFix: true, tolerance: { min: null, plus: null } }, { id: "555", groupID: "10", isFix: false, tolerance: { min: null, plus: null } }, { id: "555", groupID: "10", isFix: true, tolerance: { min: null, plus: null } }, ]
let c = b.map(obj => {
const valuesObj = a.find(item => item.id === obj.id && item.isFix === obj.isFix && item.groupid === obj.groupdid);
if (valuesObj) {
obj.tolerance.min = valuesObj.toleranceMinus || 0;
obj.tolerance.plus = valuesObj.tolerancePlus || 0;
}
return obj;
})
console.log(c);