remove current index from array of objects - javascript

I'm trying to remove the object that matches my if statement
my array:
[
TextRow {
id: 4,
user_gender: 'Male',
user_tags: '[]',
user_birth: 26,
user_lat: '34.03569255690516',
user_lng: '-6.828115666526287',
user_current_occupancy: 'None',
user_biography: null,
set_from_map: 1,
info_verified: 0
},
TextRow {
id: 5,
user_gender: 'Male',
user_relationship: 'Single',
user_tags: '[]',
user_birth: 19,
user_lat: '32.8811',
user_lng: '-6.9063',
user_current_occupancy: 'None',
user_biography: null,
set_from_map: 1,
info_verified: 0
}
]
Here is a code snippet:
in distance function, I'm calculating the destination between the user and other users that I'm having them in the data array
data.map((value, i) => {
const destination = parseFloat(
distance(lat, long, value.user_lat, value.user_lng).toFixed(2)
);
// age_range is an array that have the range of age for example[16,26]
if (
destination > location_range ||
value.user_birth < age_range[0] ||
value.user_birth > age_range[1]
) {
data.splice(i, 1);
i = i - 1;
} else value.destination = destination;
});
it didn't work for what I want, thank u in advance

const data = newData.filter(el => {
const destination = parseFloat(
distance(lat, long, el.user_lat, el.user_lng).toFixed(2)
);
console.log(
destination > location_range ||
el.user_birth < age_range[0] ||
el.user_birth > age_range[1]
);
return !(
destination > location_range ||
el.user_birth < age_range[0] ||
el.user_birth > age_range[1]
);
});
data.forEach(el => {
const destination = parseFloat(
distance(lat, long, el.user_lat, el.user_lng).toFixed(2)
);
el.destination = destination;
});

You can use data.filter instead of data.map
check this for more details https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Related

Using array, How to print name of students who has highest marks in Javascript?

The code i tried
function findHighest(){
var highest = 0; // assum min 0
var highestItem;
$('tr').each(function(index, item){
if(index > 0){
var math = $(item).find('td').eq(1).text();
var eng = $(item).find('td').eq(2).text();
var lit = $(item).find('td').eq(3).text();
//alert(math)
var sum = parseFloat(math) + parseFloat(eng) + parseFloat(lit)
if (sum > highest){
highest = sum;
highestItem = item;
}
}
})
$(highestItem).css({ 'font-style': 'italic', 'color': 'red' });
}
I am trying to find name of student who got highest marks in class in at least two subjects in JavaScript?
const highestMarks=[];
const studentsWithHighestMarks=[];
const students = [{ name: "mini", subject: [{ maths : 20}, {english: 23}, { science: 25}, { sports: 24}] }, { name: "jerry", subject: [{ maths : 22}, {english: 20}, { science: 20}, { sports: 21}] }, { name: "john", subject: [{ maths : 23}, {english: 25}, { science: 20}, { sports: 21}] }];
students.forEach(student=>{
student.subject.forEach(subject=>{
for(let key in subject){
var index = highestMarks.findIndex(obj => {
return obj.subject === key
});
if (index===-1) {
highestMarks.push({
subject:key,
marks:subject[key],
students:[student.name]
})
}else if(highestMarks[index].marks<subject[key]){
highestMarks[index].marks=subject[key];
highestMarks[index].students=[student.name];
}
else if(highestMarks[index].marks==subject[key]){
highestMarks[index].marks=subject[key];
highestMarks[index].students.push(student.name);
}
}
})
});
students.forEach(student=>{
let count=0;
highestMarks.forEach(item=>{
if(item.students.includes(student.name)){
count++;
}
});
if(count>=2){
studentsWithHighestMarks.push(student.name)
}
})
console.log(studentsWithHighestMarks)
const subjectsConsidering = 2;
const getStudentMarks = (student) => {
const studentMarksList = [];
student.subject.forEach((subjectData) => {
studentMarksList.push(Object.values(subjectData)[0]);
});
const sum = studentMarksList.sort().reverse().reduce((sum, a, index) => {
// restrict only for first 2 subjects
if (index < subjectsConsidering) {
return sum + a;
}
return sum + 0;
});
return sum;
}
students.sort((studentA, studentB) => {
//return 0 for equal marks
return getStudentMarks(studentA) > getStudentMarks(studentB) ? -1 : 1;
});
console.log(students);
//This gives the sorted array of students having the highest marks in at least 2 subjects.
// Transform the data into a more manageable format
// { "subject": [["name", grade], ["name", grade], ["name", grade]] }
let transformed = students.reduce(
(data, student) => {
student.subject.forEach(subject => {
const key = keys(subject)[0];
const grade = [student.name, subject[key]];
if (!(key in data)) {
data[key] = [];
}
data[key].push(grade);
})
return data;
},
{}
)
// Utility function to compare grades
function gradeCompare(a, b) {
return a[1] > b[1] ? -1 : 1;
}
// List the top student in each subject
let names = Object.keys(transformed).map((subject) => {
return transformed[subject].sort(gradeCompare)[0][0];
});
// names :: [ "john", "john", "mini", "mini" ]
// Count the student names
let counts = names.reduce((acc, current) => {
acc[current] = (acc[current] || 0) + 1;
return acc;
}, {});
// counts :: { john: 2, mini: 2 }
// Find the maximum occurring count
let maxCount = Math.max(...Object.values(counts));
// maxCount :: 2
// Filter the keys that have that count
let topStudents = Object.keys(counts).filter(k => counts[k] === maxCount);
// topStudents :: [ "john", "mini" ]

How to compare nested array with the map or filter and only return with first match inside?

Following are the code snippet for the data object which contains the information for the codeworks array representing the code and text.
I have one code key array like code = ["ABC","MDH"] and I want the expected out as represented into the code snippets.
const data = {
pData: {
data: [
{
codeworks: [
{
code: "MDH",
text: "Total Care MDH0"
},
{
code: "MDH",
text: "Total Care MDH1"
},
{
code: "MDH",
text: "Total Care MDH2"
}
]
},
{
codeworks: [
{
code: "ABC",
text: "Total Care ABC"
},
{
code: "MDH",
text: "Total Care MDH"
}
]
},
{
codeworks: [
{
code: "MDH",
text: "text0"
},
{
code: "XYZ",
text: "text1"
}
]
}
]
}
};
code = ["ABC","MDH"]
Expected Output : ['Total Care MDH0','Total Care ABC','text0']
I tried using the following ways,
const networkCodes = ["ABC", "MDH"];
if (
data &&
data.pData&&
data.pData.data &&
data.pData.data.length > 0
) {
const pDataItems = data.pData.data;
let filteredItems = [];
const acceptingNewItems =
pDataItems &&
pDataItems.length > 0 &&
pDataItems.forEach((providerInfoObj, index) => {
const networks =
providerInfoObj &&
providerInfoObj.codeworks&&
providerInfoObj.codeworks.length > 0 &&
providerInfoObj.codeworks;
/* eslint-disable-next-line */
for (let j = 0; j < networks.length; j++) {
const ele = networks[j];
const findNetworkCodes =
networkCodes && networkCodes.length > 0 && networkCodes;
for (let index = 0; index < findNetworkCodes.length; index++) {
const element = findNetworkCodes[index];
if (element === ele.code) {
filteredItems.push(ele.text);
}
}
}
//return filteredItems ;
});
console.log(filteredItems );
}
I did not get the output as expected into the snippets as denoted.
Thanks.
Your code is too long to understand. I think it could be expressed in short like below.
const res = data.pData.data
.map(({codeworks}) => {
const matchedCodework = codeworks.find(codework => code.includes(codework.code));
return matchedCodework ? matchedCodework.text : null;
})
.filter(text => text != null)
console.log(res)

Get combination of all elements in JavaScript Object

I'm trying to write a program that generates every single item based on my JSON structure and giving each combination an individual number. I found a function on here that so far does its job listing out every combination for me, however I cannot decipher the code to the point I actually even understand what it does. It gives me all the items, listen like Key : Value but honestly I have no idea what part of the code does what and I cannot access it in order to build in my giving them unique numbers. This is the code that I found on here (lost the thread to it):
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var input = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } },
cartesian = { eachBook: getCartesian(input.bookSet) };
It's just written in a too advanced syntax for me to remotely understand where I have to insert myself to make any calculations. I guess what I'm asking for would be either an explanation or a somewhat more understandable and modifyable code. I definitely need to run through all elements like this is doing and the output looks great from what I could tell so far, I just need to somehow calculate the keys and have an output of a number derived of each object's elements' combined keys.
An example would be book 243 for title 2, author 4 and publisher 3. I hope anyone can make sense of this. Thanks a lot!
EDIT: Included my own data and desired output. The combinations I displayed don't need to make sense.
var Product = {
json: { Product : {
assortment: [
{
name: "Yoghurt",
Flavor: ["natural", "honey", "stracciatella"],
Kind: ["greek", "soy"],
},
{
name: "Sauce",
},
{
name: "Milk Drink",
}
],
Brand: ["Oatly", "Dannon"],
Containment: ["Cup", "Jar"]
}}};
My output I'd like to generate the combinations of all of those and ultimately calculate the numbers on the right in the following screenshot
Given C_1 and C_2 two sets
The cartesian product of C_1 and C_2
is given by C_1 x C_2 = {(c_1_i,c_2_j) for c_1_i in C_1, c_2_j in C_2}
You can build C_1 x C_2 x C_3 by considering (C_1 x C_2) (that you calculated before) and "adjoining" each elem of C_3 to a tuple of C_1 x C_2
And so forth
const cartesianProduct = (C, D) => {
const res = []
C.forEach(c => {
D.forEach(d => {
// in case the tuple contains only one element (the initialization)
// make the elmeent into a tuple
const tuple = Array.isArray(c) ? c : [c]
res.push([...tuple,d])
})
})
return res
}
const nCartesianProduct = (Cs_n) => {
// we adjoin each elem of C_i and we "grow"
return Cs_n.reduce((res, C_i) => cartesianProduct(res, C_i))
}
console.log(nCartesianProduct([['b1', 'b2', 'b3'], ['t1', 't2'], ['a'], ['p']]))
Here is my attempt to lay in a simple terms:
Lets assume an example of
const sets = [ [1], [1,2], [1,2,3] ]
Possible combinations may be logged as following:
1 1 1 1 2 1
1 1 2 -> 1 2 2
1 1 3 1 2 3
Lets think of it as a clock, where last row will increase the value of previous row, once it reaches its maximum. In another words: lets increase i position of the last row and when over the limit -> drop it to zero and increase sibling instead, where if sibling is over the top -> repeat.
Consider the following code:
let sets = [[1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5] ];
let state = sets.map( () => 0 );
console.log(sets, state);
function handleIncreament(i){
if( state[i] >= sets[i].length){
if(i-1 < 0) {
console.log('end of the row');
return false;
}
state[i] = 0;
state[i-1] += 1;
return handleIncreament(i-1);
}
else {
return true;
}
}
while( handleIncreament(state.length - 1) ){
console.log( state );
state[state.length - 1]++;
}
Above will log as follows:
(4) [Array(2), Array(3), Array(4), Array(5)] (4) [0, 0, 0, 0]
(4) [0, 0, 0, 0]
(4) [0, 0, 0, 1]
(4) [0, 0, 0, 2]
(4) [0, 0, 0, 3]
(4) [0, 0, 0, 4]
(4) [0, 0, 1, 0]
(4) [0, 0, 1, 1]
(4) [0, 0, 1, 2]
...
(4) [1, 2, 3, 4]
end of the row
4
With that lets apply it to your example:
const test = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } };
sets = Object.values(test.bookSet);
state = sets.map( () => 0 );
console.log(sets, state);
const matches = [];
while( handleIncreament(state.length - 1) ){
const match = sets[0][state[0]] + ' ' + sets[1][state[1]] + ' ' + sets[2][state[2]] + ' ' + sets[3][state[3]];
matches.push( match );
state[state.length - 1]++
}
console.log(matches);
And expect to get the following:
["book1 title1 author1 publisher1", "book1 title2 author1 publisher1", "book2 title1 author1 publisher1", "book2 title2 author1 publisher1", "book3 title1 author1 publisher1", "book3 title2 author1 publisher1"]
You could take the above data without superfluous parts and simplify the result by creating a flat array of the nested properties.
The numbers of the result picture are not incuded, because of the missing relation of each value to the given data set.
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var data = {
assortment: [
{
name: "Yoghurt",
Flavor: ["natural", "honey", "stracciatella"],
Kind: ["greek", "soy"],
},
{
name: "Sauce",
},
{
name: "Milk Drink",
}
],
Brand: ["Oatly", "Dannon"],
Containment: ["Cup", "Jar"]
},
result = getCartesian(data)
.map(({ assortment: { name, Flavor = '', Kind = '' }, d = '', Brand, f = '', Containment, h = '', i = '', j = '' }) =>
[name, Flavor, Kind, d, Brand, f, Containment, h, i, j]);
console.log(result.length);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to update value in array based on values in another array?

I am having two array like this,
let array1 = [
{
"id": 23,
"name": "Telangana",
}
]
Here i need to update array2 color value inside properties based on array1 numberOfProjects value inside latestMetric. As u can see that in both arrays stateId and id are same.If numberOfProjects value is in the range 1 - 1000. I need to update the color value as 1. then numberOfProjects value is in the range 1000 - 2000. I need to update the color value as 2.so on. I dont know how to achieve this. I tried to map those two arrays and can able to get the ID's.But i dont know how to compare them and update the value . Pleas help me.Thanks in advance
You can do like this
let updatedArr2 = [];
function updateArr2(arr2values, colorValue) {
let updatedProperties = { ...arr2values.properties, color: colorValue };
arr2values.properties = updatedProperties;
updatedArr2.push(arr2values);
}
array2.map(arr2values =>
array1.map(arr1values => {
if (arr2values.properties.stateId === arr1values.latestMetric.stateId) {
if (
arr1values.latestMetric.numberOfProjects >= 1 &&
arr1values.latestMetric.numberOfProjects <= 1000
) {
updateArr2(arr2values, 1);
} else if (
arr2values.latestMetric.numberOfProjects >= 1000 &&
arr2values.latestMetric.numberOfProjects <= 2000
) {
updateArr2(arr2values, 2);
}
}
})
);
console.log(updatedArr2);
You could loop through each object in array1 and then check if there's any object in array2 that matches the stateId, if so, then check the number of projects in the array1 object and change the color of the object in array2 that has the same stateId, something like:
array1.forEach((o) => {
let matches = array2.filter(
(o2) => o2.properties.stateId === o.latestMetric.stateId
);
let projects = o.latestMetric.numberOfProjects;
for (let match of matches) {
if (projects > 1 && projects < 1000) {
match.properties.color = 1;
} else if (projects >= 1000 && projects < 2000) {
match.properties.color = 2;
}
}
});
let array1 = [
{
id: 23,
name: "Telangana",
code: "lnn",
regionId: 1,
isActive: true,
latitude: 17.8495919,
longitude: 79.1151663,
latestMetric: {
stateId: 23,
year: 0,
constructionValueInMn: 84623,
constructionAreaInMnSqft: 32,
numberOfProjects: 406,
noOfCompletedProjects: 19,
noOfOngoingProjects: 387,
noOfUpcomingProjects: 0,
growthRate: 0,
averagePricePerSqftInRs: 0,
totalAreaInMnSqft: 71,
overAllAvgSqft: 0,
eachVariantAvgSqft: 0,
noOfTypeOfVariant: 0,
projectCompletionCycle: 0,
},
createdAt: "2020-04-21T00:35:11.684134",
updatedAt: "2020-04-21T00:35:11.684134",
},
];
let array2 = [
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[77.19721, 28.861519],
[77.203836, 28.86004],
],
],
},
properties: {
cartodb_id: 26,
state_code: 7,
st_nm: "NCT of Delhi",
color: 2,
id: 23,
stateId: 23,
},
},
];
array1.forEach((o) => {
let matches = array2.filter(
(o2) => o2.properties.stateId === o.latestMetric.stateId
);
let projects = o.latestMetric.numberOfProjects;
for (let match of matches) {
if (projects > 1 && projects < 1000) {
match.properties.color = 1;
} else if (projects >= 1000 && projects < 2000) {
match.properties.color = 2;
}
}
});
console.log(array2);
Try this:
array2.map(arr2 => {
//Find to return the position when the id's are the same
const arr1 = array1.find(arr => arr.latestMetric.stateId == arr2.properties.id)
// If find was successful, do this
if (arr1) {
// Destructuring assignment to be easier to compare
const { numberOfProjects } = arr1.latestMetric
if (numberOfProjects >= 1 && numberOfProjects < 1000)
arr2.properties.color = 1
else if (numberOfProjects >= 1000 && numberOfProjects < 2000)
arr2.properties.color = 2
}
})

How to convert an unorganized array into an grouped array by id

I'm trying to create an array that contains objects with an id and amount, grouped by id. The ids needs to be unique. So if there is 2 objects with same id, the amount will be added.
I can do it with nested for-loops, but I find this solution inelegant and huge. Is there a more efficient or cleaner way of doing it?
var bigArray = [];
// big Array has is the source, it has all the objects
// let's give it 4 sample objects
var object1 = {
id: 1,
amount: 50
}
var object2 = {
id: 2,
amount: 50
}
var object3 = {
id: 1,
amount: 150
}
var object4 = {
id: 2,
amount:100
}
bigArray.push(object1,object2,object3,object4);
// organizedArray is the array that has unique ids with added sum. this is what I'm trying to get
var organizedArray = [];
organizedArray.push(object1);
for(var i = 1; i < bigArray.length; i++ ) {
// a boolean to keep track whether the object was added
var added = false;
for (var j = 0; j < organizedArray.length; j++){
if (organizedArray[j].id === bigArray[i].id) {
organizedArray[j].amount += bigArray[i].amount;
added = true;
}
}
if (!added){
// it has object with new id, push it to the array
organizedArray.push(bigArray[i]);
}
}
console.log(organizedArray);
You can definitly make it cleaner and shorter by using reduce, not sure about efficiency though, i would say a traditional for loop is more efficient :
var bigArray = [];
var object1 = {id: 1, amount: 50}
var object2 = {id: 2, amount: 50}
var object3 = {id: 1, amount: 150}
var object4 = {id: 2, amount: 100}
bigArray.push(object1, object2, object3, object4);
var organizedArray = bigArray.reduce((acc, curr) => {
// check if the object is in the accumulator
const ndx = acc.findIndex(e => e.id === curr.id);
if(ndx > -1) // add the amount if it exists
acc[ndx].amount += curr.amount;
else // push the object to the array if doesn't
acc.push(curr);
return acc;
}, []);
console.log(organizedArray)
Rather than an organized array, how about a single object whose keys are the ids and values are the sums.
var bigArray = [
{ id: 1, amount: 50 },
{ id: 2, amount: 50 },
{ id: 1, amount: 150 },
{ id: 2, amount: 100 }
];
let total = {}
bigArray.forEach(obj => {
total[obj.id] = (total[obj.id] || 0) + obj.amount;
});
console.log(total);
If you really need to convert this to an array of objects then you can map the keys to objects of your choosing like this:
var bigArray = [
{ id: 1, amount: 50 },
{ id: 2, amount: 50 },
{ id: 1, amount: 150 },
{ id: 2, amount: 100 }
];
let total = {}
bigArray.forEach(obj => {
total[obj.id] = (total[obj.id] || 0) + obj.amount;
});
console.log(total);
// If you need the organized array:
let organizedArray = Object.keys(total).map(key => ({ id: key, amount: total[key] }));
console.log(organizedArray);
function getUniqueSums(array) {
const uniqueElements = [];
const arrayLength = array.length;
for(let index = 0; index < arrayLength; index++) {
const element = array[index];
const id = element.id;
const uniqueElement = findElementByPropertyValue(uniqueElements, 'id', id);
if (uniqueElement !== null) {
uniqueElement.amount += element.amount;
continue;
}
uniqueElements.push(element);
}
return uniqueElements;
}
function findElementByPropertyValue(array, property, expectedValue) {
const arrayLength = array.length;
for(let index = 0; index < arrayLength; index++) {
const element = array[index];
const value = element[property];
if (value !== expectedValue) {
continue;
}
return element;
}
return null;
}
This is an untested code. You will be able to understand the logic. Logic is almost same yours. But, perhaps a more readable code.

Categories