Related
Actually, I meet with an iterate problem when I compare two arrays of objects.
Array Old:
[{uuid:'a'}, {uuid:'b'}, {uuid:'c'}]
Array New:
[{uuid:'a'}, {uuid:'e'}, {uuid:'f'}]
what I am going to do is calling the api under the below logic:
compare 'new' with 'old' to get the result:
[{name:1, uuid:'e'}, {name:1, uuid:'f'}]
and then call the POST api one by one to add new uuid: 'e' and 'f'
compare 'new' with 'old' to get the result:
[{name:1, uuid:'b'},{name:1, uuid:'c'}]
and then call the Delete api one by one to delete uuid: 'b' and 'c'
I have tried the below code to find the difference, but it seems not correct:(need some help)
const postArr = [];
for (var i = 0; i < this.new.length; i++) {
for (var o = 0; o < this.old.length; o++) {
if (
this.new[i].uuid !==
this.old[o].uuid
) {
postArr.push(this.new[i]);
}
}
}
console.log(postArr);
with filter and mapping u can achive uniques in old array
var a=[{uuid:'a'}, {uuid:'b'}, {uuid:'c'}];
var b=[{uuid:'a'}, {uuid:'e'}, {uuid:'f'}];
var keys = ['uuid'];
console.log(findDifferences(a,b))
function findDifferences(objectA, objectB) {
var result = objectA.filter(function(o1){
return !objectB.some(function(o2){
return o1.uuid === o2.uuid;
});
}).map(function(o){
return keys.reduce(function(newo, name){
newo[name] = o[name];
return newo;
}, {});
});
return result;
}
Try this instead:
function difference(checkingArray, baseArray) {
let diff = [];
let found = 0;
for (let j = 0; j<checkingArray.length; j++) {
found = 0;
for (let i = 0; i<baseArray.length; i++) {
if (baseArray[i].uuid == checkingArray[j].uuid) {
found = 1;
break;
}
}
if (found == 0) {
for (let k = 0; k<diff.length; k++) {
if (diff[k].uuid == checkingArray[j].uuid) {
found = 1;
break;
}
}
if (found == 0) {
diff.push(checkingArray[j]);
}
}
}
return diff;
}
let old = [{uuid:'a'}, {uuid:'b'}, {uuid:'c'}];
let recent = [{uuid:'a'}, {uuid:'e'}, {uuid:'f'}];
let onlyOnNewArray = difference(recent, old); // returns elements only in recent array not in old array
let onlyOnOldArray = difference(old, recent); // returns elements only in old array not in recent array
console.log("only on old array", onlyOnOldArray);
console.log("only on recent array", onlyOnNewArray);
I wanted to create a function, that counts all unique Items in an array, but somehow I do not get any output.
This is my array!
let arr = ["hi", "hello", "hi"];
And this is the code I wrote so far:
function countUnique(arr) {
var counts = {};
for (var i = 0; i < arr.length; i++) {
counts[arr[i]] = 1 + (counts[arr[i]] || 0);
}
countUnique(arr);
}
console.log(countUnique(arr));
Your are counting values correctly, however then you are calling this method recursively countUnique(arr); and it results an error of call stack exceeded.
So just remove recursive call of method countUnique(arr); and return counted value counts:
function countUnique(arr) {
var counts = {};
for (var i = 0; i < arr.length; i++) {
counts[arr[i]] = 1 + (counts[arr[i]] || 0);
}
return counts;
}
let arr = ["hi", "hello", "hi"];
console.log(countUnique(arr));
JavaScript engine limits the maximal recursion depth. We can rely on it being 10000, some engines allow more.
You could take a Set and return the size.
const countUnique = array => new Set(array).size;
console.log(countUnique(["hi", "hello", "hi"]));
let arr = ["hi", "hello", "hi"];
function countUnique(arr) {
var counts = {};
for (var i = 0; i < arr.length; i++) {
if(arr[i] in counts) {
counts[arr[i]]++;
} else {
counts[arr[i]] = 1;
}
}
return Object.keys(counts).length;
}
console.log(countUnique(arr));
I know it's a stupid question, but I only learning programming 3 months now.
How would you solve this problem, if you can't use higher order functions and built-in methods, like filter or indexOf?
Create a function that takes a list of numbers and returns a new list where all the duplicate values are removed
I got this so far, but I think It's a dead end...
const array = [1, 2, 3, 3, 1];
const removeDuplicate = () => {
let shortArray = [];
let index = 0;
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length; j++) {
if (i != j) {
if (array[i] == array[j]) {
shortArray[index] += array[i]
console.log(array[i]);
}
}
}
}
return shortArray;
}
console.log(removeDuplicate());
return this:
1
3
3
1
[ NaN ]
thanks!
Use an object as a helper. If a value appears in the helper, it's not unique and can be ignored. If it's not in the helper it's unique, push it into the result array, and add it to the helper object.
const array = [1, 2, 3, 3, 1];
const removeDuplicate = (arr) => {
const helperMap = {};
const result = [];
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
if (!helperMap[item]) {
result[result.length] = item;
helperMap[item] = true;
}
}
return result;
};
console.log(removeDuplicate(array));
function unique(arr) {
var obj = {};
for (var i = 0; i < arr.length; i++) {
var value = arr[i];
obj[value] = true; // set as key
}
return Object.keys(obj); //return all keys
}
Use below function:
function RemoveDuplicate(array){
let shortArray = [];
let index = 0;
for (let i = 0; i < array.length; i++) {
let exist=false;
for(let j=0;j<shortArray.length;j++){
if(array[i]==shortArray[j]){
exist=true;
break;
}
}
if(!exist){
shortArray[shortArray.length]=array[i];
}
}
return shortArray;
}
I'm trying to take this array and split it into 2 new arrays, evens and odds and return them. When I run the code below I am only getting the odds, why is that? And what can I do to solve it?
Thanks in advance.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return(evens, odds);
}
divider(numbersArray);
Because JavaScript can only return one value. Ever.
return(evens, odds)
evaluates to the same value as
return odds
due to the comma operator wrapped in grouping parenthesis.
Perhaps returning an array of arrays (or even an object of arrays) is useful..
return [evens, odds]
You should return your results as an array.
return [evens, odds];
And then to access the results:
var evens;
var odds;
var arrayResults = divider(numbersArray);
evens = arrayResults[0];
odds = arrayResults[1];
console.log(evens);
console.log(odds);
In Javascript, you can only return ONE value. So, if you want to return multiples values, to separate them, you can put them in an array or in an object :
return([evens, odds]);
OR
return({evens: evens, odds: odds})
The result of evaluating (evens, odds) is odds, that is returned thus.
This is how comma operator works.
Use the following statement instead:
return { 'evens': evens, 'odds': odds };
As an example:
var v = divider(numberArrays);
v.evens; // get evens this way
v.odds; // get odds this way
You can return only one entity from a function. Its better to wrap your results in single object.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens, odds:odds};
}
divider(numbersArray);
Es5 doesn't support tuples, You should wrap your return
in an object like here
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens,
odds:odds};
}
divider(numbersArray);
Or in an array as the other aswers show
You could return an object, like this:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens, odds};
}
divider(numbersArray);
I have this code and I want to make the code wait until the asyncrnous query called prom has finessed before restarting the first for loop. So the array will be reset, before it starts the first for loop again.
items = [];
var promises = [];
for (var i = 0; i < userArray.length; i++) {
items.length = 0;
for (var i2 = 0; i2 < test.length; i2++) {
var UserFavourite = Parse.Object.extend("UserFavourite");
var queryUserFav = new Parse.Query(UserFavourite);
queryUserFav.equalTo('item', test[i2].get('item'));
queryUserFav.equalTo('school', test[i2].get('school'));
queryUserFav.equalTo('user1', userArray[i])
var prom = queryUserFav.find().then(function(res) {
for (var i3 = 0; i3 < res.length; i3++){
var item = res[i3];
var itemName = item.get('item');
items.push(itemName);
console.log(items)
}
return items;
});
promises.push(prom);
}
//return Parse.Promise.when.apply(Parse.Promise, promises); I have tried it here but
// this just stops the first for loop after its first loop
}
return Parse.Promise.when.apply(Parse.Promise, promises);
What you're trying to do is have a chain of promises, one for each item in an array.
If would be nice if javascript had an equivalent of .NET's await keyword, where you could go
await Parse.Promise.when(promises)
and then it allowed the promise code to run then returned back to running any code after the await. But Javascript doesn't give this to us.
Another approach is to maintain an index variable. After every set of queries is processed, you increment the index variable and process the next set of values.
function parseForUser(user) {
var promises = [];
for (var i2 = 0; i2 < test.length; i2++) {
var items = [];
var UserFavourite = Parse.Object.extend("UserFavourite");
var queryUserFav = new Parse.Query(UserFavourite);
queryUserFav.equalTo('item', test[i2].get('item'));
queryUserFav.equalTo('school', test[i2].get('school'));
queryUserFav.equalTo('user1', user)
var prom = queryUserFav.find().then(function(res) {
for (var i3 = 0; i3 < res.length; i3++){
var item = res[i3];
var itemName = item.get('item');
items.push(itemName);
console.log(items)
}
return items;
});
promises.push(prom);
}
return Parse.Promise.when(promises);
}
function parseUserArray(userArray) {
var returnPromise = new Parse.Promise(); // Do you have to call it via new?
//The documentation isn't clear.
var index = 0;
var doNext = function() {
if(index < userArray.length) {
var promise = parseForUser(userArray[index++]);
promise.done(doNext);
} else {
returnPromise.resolve();
}
}
doNext();
return returnPromise;
}
var parseUserArrayPromise = parseUserArray(userArray);
FWIW ...
This solution differs from #AndrewShepherd's chiefly in that here we take double advantage of the promise returned by asyncProcessUser().
firstly for flow control - the asynchronous sequencing of the inner loop
secondly for delivering an array of results, from which the final array of results is built, avoiding the need for an outer promises array.
function parseUserArray(userArray, test) {
// This function is the original inner for() loop, now expressed as a .map(),
// (plus peripheral wrapping and chaining).
// It asynchronously processes a single user against all test items,
// and returns a promise of an array of results.
// The promise resolves when all the individual .finds complete.
function asyncProcessUser(user) {
return Parse.Promise.when(test.map(function(dataItem) {
return (new Parse.Query(Parse.Object.extend("UserFavourite")))
.equalTo('item', dataItem.get('item'))
.equalTo('school', dataItem.get('school'))
.equalTo('user1', user)
.find().then(function(res) {
return res.map(function(r) {
return r.get('item');
});
});
})).then(function() {
return Array.prototype.slice.apply(arguments).reduce(function(arr, arr_) {
return arr.concat(arr_);
}, []);
});
}
// This is the original outer for() loop, now expressed as a .reduce(), which is
// a common pattern for performing a series of async tasks (ie what was the inner loop).
// Here, `userArray.reduce(...)` returns a promise of an array of
// the objects returned by `r.get('item')` above.
return userArray.reduce( function(p, user) {
return p.then(function(arr) {
return asyncProcessUser(user).then(function(arr_) {
return arr.concat(arr_);
});
});
}, Parse.Promise.as([]) );//† "returns a new promise that is resolved with a given value".
}
† : Documentation for Parse.Promise.as()
Without the comments, it's quite concise.
The concept is demonstrated here. Don't worry that the demo uses jQuery promises, it's the concept that matters.
Use this
function parseForUser(user) {
var promises = [];
for (var i2 = 0; i2 < test.length; i2++) {
var items = [];
var UserFavourite = Parse.Object.extend("UserFavourite");
var queryUserFav = new Parse.Query(UserFavourite);
queryUserFav.equalTo('item', test[i2].get('item'));
queryUserFav.equalTo('school', test[i2].get('school'));
queryUserFav.equalTo('user1', user)
var prom = queryUserFav.find().then(function(res) {
for (var i3 = 0; i3 < res.length; i3++){
var item = res[i3];
var itemName = item.get('item');
items.push(itemName);
console.log(items)
}
return items;
});
promises.push(prom);
}
return Parse.Promise.when(promises);
}
function parseUserArray(userArray) {
var returnPromise = new Parse.Promise(); // Do you have to call it via new?
//The documentation isn't clear.
var index = 0;
var doNext = function() {
if(index < userArray.length) {
var promise = parseForUser(userArray[index++]);
promise.done(doNext);
} else {
returnPromise.resolve();
}
}
doNext();
return returnPromise;
}
Just copy and paste