The Question is
Create a function called divisibles() that will take each object in upper and find all
objects in lower that evenly divide into it, ignoring zero. The function should return an
object that is upper but each object has an additional key called found and the value
for that key is an array containing each item from lower that was evenly divided into it.
Output the result of the function to the console.
Here's my code so far, I know I'm doing something very wrong and can't figure it out. I have it in two functions, can't figure out how to make it one, and my output doesn't look correct either.
function divisibles(number, myArrayLower) {
let divisibleArray = [];
let count = 0;
for (let i = 0; i < myArrayLower.length; i++) {
if (number % myArrayLower[i].value === 0) {
divisibleArray[count++] = {name: myArrayLower[i].name, value: myArrayLower[i].value};
}
}
return divisibleArray;
}
function findDivisibles(myArrayUpper, myArrayLower) {
let divisiblesArray = [];
for (let i = 0; i < myArrayUpper.length; i++) {
let divisibleArray = divisibles(myArrayUpper[i].value, myArrayLower);
divisiblesArray[i] = {
name: myArrayUpper[i].name, value: myArrayUpper[i].value,
found: divisibleArray
};
}
return divisiblesArray;
}
Here's the call function
let resultArray = findDivisibles(myArrayUpper, myArrayLower);
Here is my console.log
let resultArray = findDivisibles(myArrayUpper, myArrayLower);
for (let i = 0; i < resultArray.length; i++) {
console.log("Name: " + resultArray[i].name + " Value: " + resultArray[i].value + " Found: ");
let tmpArray = resultArray[i].found;
for (let k = 0; k < tmpArray.length; k++) {
console.log(" Name: " + tmpArray[k].name + " Value: " + tmpArray[k].value);
}
}
The desired output will look something like this
{
name: ”Nathan15”,
value: 15,
found:[
{ name: “nathan3”, value: 3},
{ name: “nathan15”, value: 15} ]
}
This is my output
My output looks like this
Name: Nathan586 Value: 2930 Found:
Name: Nathan587 Value: 2935 Found:
Name: Nathan588 Value: 2940 Found:
Name: nathan1 Value: 3
Name: nathan2 Value: 6
Name: nathan4 Value: 12
I can add the rest of the question, code I wrote for previous parts of this question if it helps
Related
I've got an array of objects, these objects have an identifiers array with strings. One of these strings contains a Discord ID. The problem is its position is changing all the time, so I can't use the 4th identifier for example.
I only need the discord property.
I tried many things. I think it should be something like only "discord" property, but I have no idea how to solve that and code that up. Click on image to see more. There's json file there. It's all about ${players[i].identifiers[4]
const updateMessage = function() {
getVars().then((vars) => {
getPlayers().then((players) => {
if (players.length !== LAST_COUNT) log(LOG_LEVELS.INFO,`${players.length} graczy`);
let queue = vars['Queue'];
let embed = UpdateEmbed()
.addField('Status serwera','<:tak:847199217063297056> Online',true)
.addField('W kolejce',queue === 'Enabled' || queue === undefined ? '0' : queue.split(':')[1].trim(),true)
.addField('Graczy online',`${players.length}/${MAX_PLAYERS}\n\u200b\n`,true);
// .addField('\u200b','\u200b\n\u200b\n',true);
if (players.length > 0) {
// method D
const fieldCount = 3;
const fields = new Array(fieldCount);
fields.fill('');
// for (var i=0;i<players.length;i++) {
// fields[i%4 >= 2 ? 1 : 0] += `${players[i].name}${i % 2 === 0 ? '\u200e' : '\n\u200f'}`;
// }
fields[0] = `**Mieszkańcy na wyspie:**\n`;
for (var i=0;i<players.length;i++) {
fields[(i+1)%fieldCount] += `${players[i].name} [${players[i].id}], ${players[i].identifiers[4]}`;
}
for (var i=0;i<fields.length;i++) {
let field = fields[i];
if (field.length > 0) embed.addField('\u200b',`\n${fields[i]}`, true);
}
}
sendOrUpdate(embed);
LAST_COUNT = players.length;
}).catch(offline);
}).catch(offline);
TICK_N++;
if (TICK_N >= TICK_MAX) {
TICK_N = 0;
}
for (var i=0;i<loop_callbacks.length;i++) {
let callback = loop_callbacks.pop(0);
callback();
}
};
If I understand you correctly, you want to get the element from the identifiers array, but its position is not fixed, it can be anywhere.
Luckily, the element always start with the word 'discord', so you can use Array#find() with String#startsWith() to find your discord ID. Check out the snippet below:
let players = [{
id: 1,
identifiers: ["license:57349756783645", "xbl:85437852", "live:8953291341", "discord:89325813521519", "fivem:893123"],
name: "foo",
ping: 56
}, {
id: 2,
identifiers: ["xbl:57420987", "live:09123489", "discord:86543932136453", "license:865496782134", "fivem:584723"],
name: "bar",
ping: 41
}, {
id: 3,
identifiers: ["live:99532945", "discord:80521578413532", "license:60795634523", "xbl:1239435", "fivem:943921"],
name: "bar",
ping: 41
}]
players.forEach(player => {
let discord = player.identifiers.find(i => i.startsWith('discord')).replace('discord:', '')
console.log(`
ID: ${player.id}
Name: ${player.name}
Discord: ${discord}
`)
})
// ...
fields[0] = `**Mieszkańcy na wyspie:**\n`;
for (var i = 0; i < players.length; i++) {
const discord = players[i].identifiers.find((el) =>
el.startsWith('discord'),
).replace('discord:', '');
fields[
(i + 1) % fieldCount
] += `${players[i].name} [${players[i].id}], ${discord}`;
}
// ...
I’m having a lot of trouble learning how to use for loops to fill a new variable. As an example say if I have var year = [2010, 2000, 1992]; and var age = [];.
How would I use a for loop to fill in the age variable?
If this is a bad example, don’t use this. I just would like some help with understanding how to fill in empty arrays.
var names = ["Ace", "yoshi", "Lassie"];
var age = [25, 23, 5];
var u24 = [];
for (var i = 0; i < names.length; i++) {
if ([age] < 24) {
u24 += age[i]
console.log("hello " + names + " " + "you are" + age);
}
}
It is better to create objects that contain relevant data. Combining the name and age into a person object would help.
var persons = [
{
name: "Ace",
age: 25
},
{
name: "yoshi",
age: 23
},
{
name: "Lassie",
age: 5
}
];
var u24=[];
for (var i =0; i < persons.length; i++) {
var person = persons[i];
if(person.age < 24){
u24.push(person.age);
console.log("hello " + person.name + " " + "you are " + person.age);
}
}
console.log(u24);
But you can also use forEach like this:
var persons = [
{
name: "Ace",
age: 25
},
{
name: "yoshi",
age: 23
},
{
name: "Lassie",
age: 5
}
];
var u24=[];
persons.forEach(
function(person) {
if(person.age < 24){
u24.push(person.age);
console.log("hello " + person.name + " " + "you are " + person.age);
}
}
);
console.log(u24);
By making objects that include all relevant data your loops will never get out of sync. If you remove a person from the persons array then their name and age will go together.
UPDATE: Using a filter
var persons = [
{
name: "Ace",
age: 25
},
{
name: "yoshi",
age: 23
},
{
name: "Lassie",
age: 5
}
];
var youngPersons = persons.filter(
function(person) {
return (person.age < 24);
}
);
console.log(youngPersons);
Or using an ES6 Arrow Function
var persons = [
{ name: "Ace", age: 25 },
{ name: "yoshi", age: 23 },
{ name: "Lassie", age: 5 }
];
var youngPersons = persons.filter((person) => person.age < 24);
console.log(youngPersons);
This provides back an array of the persons that match your Age under 24 criteria.
If all you want to do is fill in the age array with a loop, you can try this:
let years = [2010, 2000, 1992],
age = [],
d = new Date().getFullYear();
years.forEach(year => age.push(d - year));
console.log(age);
As regards the relationship between age and names, I think Intervalia has explained that.
A working version.
Please compare it with your code to see the differences. Arrays always got me when I was starting out, and the syntax with different across languages, despite the reuse of bracket symbols.. AutoIt language still trips me up :P
var names = ["Ace", "yoshi", "Lassie"];
var age = [25, 23, 5];
//Use array.push() to append values
var u24 = [];
//variable i counts up to names.length
//because i++ means 'add one' to i
for (var i = 0; i < names.length; i++) {
//if ([age] < 24) {u24 += age[i];
//age at the count 'i' (which is
//counting)
//is achieved by array[at_index]
if (age[i] < 24) {
u24.push(age[i]); //add it to the end
console.log("Hello " + names[i] +
", you are " + age[i]);
}
}
This question already has answers here:
Modifying a copy of a JavaScript object is causing the original object to change
(13 answers)
Closed 5 years ago.
Here is the code i have:
let testp = {
value: ''
}
let data = [];
for (let i = 0; i < 5; i++) {
testp.value = i;
data.push(testp);
}
console.log(data)
The data return is:
[ { value: 4 },
{ value: 4 },
{ value: 4 },
{ value: 4 },
{ value: 4 } ]
why? I think the result is like this:
[ { value: 0 },
{ value: 1 },
{ value: 2 },
{ value: 3 },
{ value: 4 } ]
You're pushing a reference to the object testp into the array 5 times, editing the value of value each time.
Here's another example:
let foo = { 'a': 1 };
let bar = [foo, foo, foo];
foo.a = 2;
console.log(foo[2]);
// 2
The array bar contains three references to foo. Changing the content of the object will change the content of the object everywhere it is referenced.
If you want new objects you have to create them somewhere. For example:
// Function that constructs the new objects
let foo = (value) => { return { "value": value } };
let data = [];
for (let i = 0; i < 5; i++) {
data.push(foo(i));
}
Assigning testp.value inside the loop was causing the problem.Instead you could do
let testp = {
value: ''
}
let data = [];
for (let i = 0; i < 5; i++) {
data.push({
value: i
});
}
console.log(data)
I am attempting to get the following JavaScript comparator function for an array which contains objects (keyed) but the below code isn't working.
I have tried many examples online (changing them per my needs) but so far no good.
See below for the code. What am I doing wrong?
Thank you for your time.
(As an FYI, the teContainer object below get's filled via an AJAX call)
var teContainer = {};
for (var i = 0; i < result.d.length; i++) {
var key = result.d[i].PersonId;
teContainer[key] = {
displayText: result.d[i].DLSPersonId + ' ' + result.d[i].PersonLastName + ', ' + result.d[i].PersonFirstName.substring(0, 5),
tEFirstName: result.d[i].PersonFirstName,
tELastName: result.d[i].PersonLastName,
tEID: result.d[i].PersonId,
orgID: result.d[i].DLS_OrgId
};
}
function tECompare(a, b) {
if (a.tELastName < b.tELastName)
return -1;
if (a.tELastName > b.tELastName)
return 1;
return 0;
}
teContainer.sort(tECompare);
Edit: Thanks to the answer; here is the corrected code which works:
var teContainer = [];
for (var i = 0; i < result.d.length; i++) {
teContainer.push = ({
displayText: result.d[i].DLSPersonId + ' ' + result.d[i].PersonLastName + ', ' + result.d[i].PersonFirstName.substring(0, 5),
tEFirstName: result.d[i].PersonFirstName,
tELastName: result.d[i].PersonLastName,
tEID: result.d[i].PersonId,
orgID: result.d[i].DLS_OrgId
});
}
function tECompare(a, b) {
if (a.tELastName < b.tELastName)
return -1;
if (a.tELastName > b.tELastName)
return 1;
return 0;
}
teContainer.sort(tECompare);
It's not running because sort isn't a method of an object. teContainer is an object, not an array. You're probably getting the following error:
Calling undefined method "sort"
In general your code is good. The main thing about sorting, is that the 'sort' function only works with Array, not with Object.
Assuming an Ajax result formatted as:
var result = {
d: [
{
PersonId: 1,
DLSPersonId: 1,
PersonLastName: "Doe",
PersonFirstName: "John",
DLS_OrgId: 1
},
{
PersonId: 2,
DLSPersonId: 2,
PersonLastName: "Smith",
PersonFirstName: "Alex",
DLS_OrgId: 2
},
{
PersonId: 3,
DLSPersonId: 3,
PersonLastName: "Vera",
PersonFirstName: "Luis",
DLS_OrgId: 3
}
]
};
Here is a demo
*In the demo, I didn,t chnage your teContainer object in case you need it like it is.
I am trying to build a 3-tiered function:
First, an array lists available workshops (array is called 'workshops').
Second, another array lists workshops that a user has selected (this array is called 'selectedWorkshops').
Third, I have a final array called 'registeredWorkshops'.
When my function is run, I want objects within 'selectedWorkshops' to be added to 'registeredWorkshops', then I want to delete any objects within 'selectedWorkshops' from both 'selectedWorkshops' and any matching elements from 'workshops'. So, where those objects used to exist in both 'selectedworkshops' and 'workshops', now they only exist in 'registeredWorkshops'.
Here's what I've got so far:
addRemoveWorkshops = function(){
var numberOfWorkshops = selectedWorkshops.length;
for(var i = 0; i < numberOfWorkshops; i++ ){
registeredWorkshops.push(selectedWorkshops[i]);
for(var j = 0, arrayLength = workshops.length; j < arrayLength; j++) {
var searchTerm = selectedWorkshops[i].WorkshopId;
if (workshops[j].WorkshopId === searchTerm) {
workshops = workshops.slice(j);
}
}
selectedWorkshops = selectedWorkshops.slice(i);
}
};
addRemoveWorkshops();
However, the function doesn't appear to work properly. It doesn't seem to be deleting the correct workshops, and it only seems to add one of the selectedWorkshops to registeredWorkshops. What am I doing wrong?
Here's a codepen demonstration: http://codepen.io/trueScript/pen/GgVWMx
If it's not possible to add other properties to the objects (as per my other answer) then I'd tackle it like this:
function registration(workshops, selected, registered) {
// add the selected workshops to registered
selected.forEach(function(workshop) {
registered.push(workshop);
});
// remove them from the other lists
registered.forEach(function(workshop) {
removeWorkshop(selected, workshop);
removeWorkshop(workshops, workshop);
});
}
function removeWorkshop(list, workshop) {
var index = list.indexOf(workshop);
if(index >= 0) {
list.splice(index, 1);
}
}
The function expects each of the arrays to be passed in as arguments and it will modify them in place. Things always become clearer and easier to test if you move your loops out into functions before nesting them.
There should be no reason not to use the indexOf method here, as it saves you having to write an extra loop. However, if for some reason you needed to use the WorkshopId property to locate the item within the list, you could create another helper method to do this for you.
function findWorkshop(list, workshop) {
for(var i = 0; i < list.length; i++) {
if(list[i].WorkshopId === workshop.WorkshopID) {
return i;
}
}
return -1;
}
Then you just amend the removeWorkshop function to reflect that.
function removeWorkshop(list, workshop) {
var index = findWorkshop(list, workshop);
list.splice(index, 1);
}
I think it would be easier to slightly rethink your data structure. If you go for the imperative solution above, you run this risk of ending up with duplicate values in more than one list.
Would it not be easier to add registered and selected properties to your workshop objects?
var workshops = [
{
name: 'apples',
WorkshopId: '19',
registered: true,
selected: false
},
{
name: 'oranges',
WorkshopId: '3b',
selected: true,
registered: false
},
// ...
];
Then if you need to be able to get a list of all the registered workshops, you can create it using a filter.
// helper function for filtering based
// on a given property
function property(name) {
return function(object) {
return object[name];
}
}
var registered = workshops.filter(property('registered'));
var selected = workshops.filter(property('selected'));
To select a workshop, all you need to do is change the select property to true:
workshops[3].selected = true;
You could then write the original function to register all workshops that were selected like this:
function registration(workshops) {
workshops.forEach(function(workshop) {
if(workshop.selected) {
workshop.registered = true;
workshop.selected = false;
}
});
}
A while loop + a for one :
var workshops = [{
name: 'apples',
WorkshopId: '19'
}, {
name: 'oranges',
WorkshopId: '3b'
}, {
name: 'pears',
WorkshopId: 'x6'
}, {
name: 'pineapples',
WorkshopId: '55'
}, {
name: 'watermelons',
WorkshopId: '8v'
}];
var selectedWorkshops = [{
name: 'oranges',
WorkshopId: '3b'
}, {
name: 'watermelons',
WorkshopId: '8v'
}, {
name: 'pears',
WorkshopId: 'x6'
}];
var registeredWorkshops = [];
var numberOfWorkshops;
addRemoveWorkshops = function () {
numberOfWorkshops = selectedWorkshops.length;
// A single while statment is enough and lighter
while (selectedWorkshops.length) {
var removedWorkshop;
numberOfWorkshops = registeredWorkshops.push(selectedWorkshops[0]);
for (var i = 0; i < workshops.length; i++)
if (workshops[i].WorkshopId == selectedWorkshops[0].WorkshopId) {
workshops.splice(i, 1);
break;
}
selectedWorkshops.splice(0, 1);
}
};
addRemoveWorkshops();
// Better for viewing the content (in firefox I have just "Object") :
console.log("workshops : ");
for (var i = 0; i < workshops.length; i++)
console.log('- ' + workshops[i].name);
console.log("selectedWorkshops : ");
for (var i = 0; i < selectedWorkshops.length; i++)
console.log('- ' + selectedWorkshops[i].name);
console.log("registeredWorkshops : ");
for (var i = 0; i < registeredWorkshops.length; i++)
console.log('- ' + registeredWorkshops[i].name);
addRemoveWorkshops = function(){
var numberOfWorkshops = selectedWorkshops.length;
for(var i = 0; i < numberOfWorkshops; i++ ){
registeredWorkshops.push(selectedWorkshops[i]);
for(var j = 0, arrayLength = workshops.length; j < arrayLength; j++) {
var searchTerm = selectedWorkshops[i].WorkshopId;
if (workshops[j].WorkshopId === searchTerm) {
workshops = workshops.splice(j,1);
}
}
selectedWorkshops = selectedWorkshops.splice(i,1);
}
};