Delete a duplicate object in array when fill one by one - javascript

I have an array of objects that some of them are the same (duplicate).
in a loop of .forEach(). inside a callback function i want to remove a duplicate object when they enter to another array one by one. i tried to loop every iteration on the array to find and remove duplicate but for some reason i can not get it.
I tried to make a loop and slice the duplicate.
I can not make a function.
I can not get the whole array and handle the duplicates.
.forEach(function(snap){
groupsJoin.push({groupId: snap)}
groupsJoin.sort((a, b) => (a.groupId > b.groupId) ? -1 : 1)
for (z=1; z<groupsJoin.length; z++) {
if (groupsJoin[z-1].groupId === groupsJoin[z].groupId) {
groupsJoin = groupsJoin.slice(0, z)
}
...Object.assign({}, groupsJoin)
}

You could use the Set data structure. Just create a new Set by passing the array and it will automatically remove duplicates
let set1 = new Set(yourArray)
For more information, see the documentation

In case you can't use new Set(groupsJoin) to filter all of them at once, you refer to the following solution :
var groupsJoin = new Set();
arr.forEach(x => groupsJoin.add(x))
As result, you'll get an array with unique values.
if there is need to keep maps inside, instead of x, use
x.groupId => groupsJoin.add(x.groupId)
It will depend on your context.
var arr = [1, 2, 4, 5, 5, 4, 3, 9, 8, 11, 1];
var groupsJoin = new Set();
arr.forEach( x => groupsJoin.add(x));
console.log(groupsJoin);

Related

Using a loop to increment each slot of an array by 1. The size of the array is the argument passed into a function

i am trying to solve a code challenge that asks me to fill an array with the value passed as an argument in a function.
For example = fizzBuzz(10)
should return an Array with 10 slots and for each slot increment 1
[0, 1, 2, 3 ,4, 5, 6, 7, 8, 9, 10]
i have tried with a loop and with the fill method but i am having difficulties on this.
This is the first step of the algorithm. Can someone help me ?
Here is my last attempt:
function fizzbuzz(n) {
// Write your code here
const array = new Array(n)
for(let i = 0; i < n; i++) {
array.fill(n, 0))
}
return array
}
This wont work cause the fill method is only called once for every slot i guess. Can someone help me ?
I have tried with the forEach method, fill method and with a loop, but i am unable to solve the first step of this algorithm.
I need nelp solving the first step of this algorithm.
So: you are learning to use arrays.
Let's start with the basics.
An array is a kind of variable that points to a list of things.
Javascript simulates traditional arrays by numbering each element:
const array = new Array(10);
But javascript is not vary rigid about how many elements are in an array, so you could also say:
const array = [];
There's a difference between these two, even though absolutely nothing is in it yet: the first form has 10 undefined values. The second form as no values and a length of 0. But they both work just fine.
How do you access elements in this list? By number!
console.log(array[0]);
In both of the above cases, you are going to get "undefined" as a result.
Now to understand your homework, all you need to know is how to assign values to the array. The array object method "fill" is no good, because what your initial loop does is assign ALL elements to 0, and then to 1, and then to 2, etc. That's no good. Who knows why we even have a "fill" method. I've never used it in my life.
But what happens ALL THE TIME is:
const array = [];
for (let i=0; i < n; i++) {
array[i] = i;
}
What is happening here?
The element in the list at position 0 is set to 0.
The element in the list at position 1 is set to 1.
And so on.
Because it is javascript, there are actually MANY ways to do this. This is just one. Using "fill" is not one. But this is the most fundamental pattern common across most languages, so it is a good one to master before moving on to fancier approaches.
If you are trying to created an Array of size N with values from 0...N then the size of the array should be N + 1.
For initializing the array
You can use ES6 using Array
keys() and spread operator.
const N = 10;
const array = [...Array(N+1).keys()]
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
If you want to use for loop, then you can populate the array like this:
const N = 10;
const array = new Array(N+1);
for(let i=0; i<array.length; i++) {
array[i] = i;
}
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
How to create an array containing 1...N

How to change position of items within an array?

I am trying to create a function that changes positions of the items inside an array.
For example, I have this array:
[1, 2, 3] - if I call the function I get this => [2, 3, 1];
If I call the function again I should have this => [3, 1, 2];
The next time it should move again and so on.
But instead, if I call the function a second time I get this again => [2, 3, 1];
How could I make this work properly?
I know why this is happening, every time I call the function it receives the same values in the same order, I get that, that's why I built another array (move) to receive the values in the current order, it was an attempt to use this new array the second time I call the function, I tried it using an if/else statemente, but it didn't work; I also built another function passing 'move' as a parameter, and it worked, but just doesn't make any sense I have to have a different function for every move.
p.s. I am receiving the values from a HTML input.
<input id="numero1" value="">
<button onclick="moveLeft()">Move</button>
var n1 = document.getElementById("numero1");
function moveLeft() {
var str = n1.value;
var arr = str.split('');
var move = [];
console.log(arr);
arr.splice(0, 3, arr[1], arr[2], arr[0]);
console.log(arr);
for (var i = 0; i < arr.length; i++) {
move.push(arr[i]);
}
console.log(move);
teste(move);
}
function teste(move) {
console.log(move);
move.splice(0, 3, move[1], move[2], move[0]);
console.log(move);
}
If I understood properly, I think you can simplify in one line function:
const moveLeft = (arr) => arr.push(a.shift());
Notice that this function would mutate the content of the array but I guess that what you want:
const array = [1, 2, 3];
moveLeft(array);
console.log(array)// [2, 3, 1]
moveLeft(array);
console.log(array)// [3, 1, 2]
moveLeft(array);
console.log(array)// [1, 2, 3]
Basically with push we add a new element at the end of the array, and the new element we add, is the return value of the method shift, that removes the first element from an array and return it.
Edit
If you don't want to mutate the original array, the fastest way is create a shallow copy and pass that to the function:
const newArray = array.slice();
moveLeft(newArray);
console.log(newArray, array) // [2, 1, 3] [1, 2, 3]
However, a possible implementation that always return a new array, could be:
const moveLeft = (arr) => [...arr.slice(1), arr[0]]
Just for future reference. But keep in mind that here you're create a shallow copy, (so one new array) and returns a new array from the spread operator, so it's less ideal. It could be useful only if you're writing an API that never allow mutability.
Edit 2
As per comment, the input's value should reflect the new order, so, given the moveLeft function written before (the first one, that mutates the content):
<input id="numero1" value="">
<button onclick="inputMoveLeft('numero1')">Move</button>
And the JS:
function inputMoveLeft(id) {
const input = document.getElementById(id);
input.value = moveLeft(input.value.split("")).join("");
}
It should give you the result you were looking for.
pop and shift sound like the thing you need:
function rotateLeft(array){
let first = array.shift()
array.push(first); // add to end
return array;
}
function rotateRight(array){
let last = array.pop()
array.unshift(last); // add to front
return array;
}

JS Array.sort. How to remove matching value from array

I am performing an Array.sort with the compare method like so:
orderNotes(notes){
function compare(a, b) {
const noteA =a.updatedAt
const noteB =b.updatedAt
let comparison = 0;
if (noteA < noteB) {
comparison = 1;
} else if (noteA > noteB) {
comparison = -1;
}
return comparison;
}
return notes.sort(compare)
}
Now since I need to sort the array anyway and loop through each element with the Array.sort, I want to use this chance to check if the note.id matches on the neighboring note, and remove the duplicate from the array (doesn't matter which one). This will save me the trouble to loop again just to check duplication.
Is it possible to alter the array inside the compare() function and remove the duplicate?
Best
Is it possible to alter the array inside the compare() function and remove the duplicate?
You could .splice(...) the element out of it if it doesn't match, but actually this:
This will save me the trouble to loop again just to check duplication.
Is a missconception. Looping an array and doing two tasks will only be slightly faster than two loops, as only the looping part gets duplicated, not the tasks done in the loop. Therefore just:
const ids = new Set;
const result = array
.filter(it => ids.has(it.id) && ids.add(it.id))
.sort((a, b) => a.updatedAt - b.updatedAt);
It might be a simpler solution to use Array.prototype.reduce to remove the duplicates in an additional step instead of while sorting:
//Starting with your ordered array
var ordered = [1, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 8, 9, 9, 9];
//Now create a new array excluding the duplicates
var orderedAndUnique = ordered.reduce((accum, el) => {
if (accum.indexOf(el) == -1) {
accum.push(el);
return accum;
}
return accum;
}, []);
console.log(orderedAndUnique);

Duplicate an array an arbitrary number of times (javascript)

Let's say I'm given an array. The length of this array is 3, and has 3 elements:
var array = ['1','2','3'];
Eventually I will need to check if this array is equal to an array with the same elements, but just twice now. My new array is:
var newArray = ['1','2','3','1','2','3'];
I know I can use array.splice() to duplicate an array, but how can I duplicate it an unknown amount of times? Basically what I want is something that would have the effect of
var dupeArray = array*2;
const duplicateArr = (arr, times) =>
Array(times)
.fill([...arr])
.reduce((a, b) => a.concat(b));
This should work. It creates a new array with a size of how many times you want to duplicate it. It fills it with copies of the array. Then it uses reduce to join all the arrays into a single array.
The simplest solution is often the best one:
function replicate(arr, times) {
var al = arr.length,
rl = al*times,
res = new Array(rl);
for (var i=0; i<rl; i++)
res[i] = arr[i % al];
return res;
}
(or use nested loops such as #UsamaNorman).
However, if you want to be clever, you also can repeatedly concat the array to itself:
function replicate(arr, times) {
for (var parts = []; times > 0; times >>= 1) {
if (times & 1)
parts.push(arr);
arr = arr.concat(arr);
}
return Array.prototype.concat.apply([], parts);
}
Basic but worked for me.
var num = 2;
while(num>0){
array = array.concat(array);
num--}
Here's a fairly concise, non-recursive way of replicating an array an arbitrary number of times:
function replicateArray(array, n) {
// Create an array of size "n" with undefined values
var arrays = Array.apply(null, new Array(n));
// Replace each "undefined" with our array, resulting in an array of n copies of our array
arrays = arrays.map(function() { return array });
// Flatten our array of arrays
return [].concat.apply([], arrays);
}
console.log(replicateArray([1,2,3],4)); // output: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
What's going on?
The first two lines use apply and map to create an array of "n" copies of your array.
The last line uses apply to flatten our recently generated array of arrays.
Seriously though, what's going on?
If you haven't used apply or map, the code might be confusing.
The first piece of magic sauce here is the use of apply() which makes it possible to either pass an array to a function as though it were a parameter list.
Apply uses three pieces of information: x.apply(y,z)
x is the function being called
y is the object that the function is being called on (if null, it uses global)
z is the parameter list
Put in terms of code, it translates to: y.x(z[0], z[1], z[2],...)
For example
var arrays = Array.apply(null, new Array(n));
is the same as writing
var arrays = Array(undefined,undefined,undefined,... /*Repeat N Times*/);
The second piece of magic is the use of map() which calls a function for each element of an array and creates a list of return values.
This uses two pieces of information: x.map(y)
x is an array
y is a function to be invoked on each element of the array
For example
var returnArray = [1,2,3].map(function(x) {return x + 1;});
would create the array [2,3,4]
In our case we passed in a function which always returns a static value (the array we want to duplicate) which means the result of this map is a list of n copies of our array.
You can do:
var array = ['1','2','3'];
function nplicate(times, array){
//Times = 2, then concat 1 time to duplicate. Times = 3, then concat 2 times for duplicate. Etc.
times = times -1;
var result = array;
while(times > 0){
result = result.concat(array);
times--;
}
return result;
}
console.log(nplicate(2,array));
You concat the same array n times.
Use concat function and some logic: http://www.w3schools.com/jsref/jsref_concat_array.asp
Keep it short and sweet
function repeat(a, n, r) {
return !n ? r : repeat(a, --n, (r||[]).concat(a));
}
console.log(repeat([1,2,3], 4)); // [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
http://jsfiddle.net/fLo3uubk/
if you are inside a loop you can verify the current loop index with the array length and then multiply it's content.
let arr = [1, 2, 3];
if(currentIndex > arr.length){
//if your using a loop, make sure to keep arr at a level that it won't reset each loop
arr.push(...arr);
}
Full Example:
https://jsfiddle.net/5k28yq0L/
I think you will have to write your own function, try this:
function dupArray(var n,var arr){
var newArr=[];
for(var j=0;j<n;j++)
for(var i=0;i<arr.length;i++){
newArr.push(arr[i]);
}
return newArr;
}
A rather crude solution for checking that it duplicates...
You could check for a variation of the length using modulus:
Then if it might be, loop over the contents and compare each value until done. If at any point it doesn't match before ending, then it either didn't repeat or stopped repeating before the end.
if (array2.length % array1.length == 0){
// It might be a dupe
for (var i in array2){
if (i != array1[array2.length % indexOf(i)]) { // Not Repeating }
}
}

Javascript: is there a data structure, "matrix", thing[x][y]?

I don't know the terminology but I want to get it simpler:
var thingTopic1 =['hello','hallo', ..., 'hej'];
var thingTopic2 =['a','b',...,'c'];
...
var thingTopic999 =['x,'y',...,'?'];
so I want to access the data like thing[para1][para2], is there some ready data structure for it or do I need to create messy function with the things? Please, note that sizes of things differ.
You can have arrays of arrays, and the size of each row can be different.
var matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0]
];
The variable "matrix" will refer to an array with length 4. The syntax you use to refer to (say) the "5" in the second row is exactly what you suggested:
var theFive = matrix[1][1];
You can "build" a matrix like that incrementally of course.
var matrix = [];
for (var i = 1; i < 10; ++i) {
var row = ~~((i - 1) / 3);
if (!matrix[row]) matrix[row] = [];
matrix[row][(i - 1) % 3] = i;
}
matrix.push([0]);
When you set an integer-indexed "property" of an Array instance, Javascript makes sure that the "length" property of the array is updated. It does not allocate space for "holes" in the array, so if you set element number 200 first, there's still just one thing in the array, even though "length" would be 201.
No, there is no data structure for that, but you can easily accomplish it by combining arrays.
You can create an array that contains arrays, which is called a jagged array:
var thing = [
['hello','hallo','goddag','guten tag','nuqneH','hej'],
['a','b','c','d','e','f','g','h','i','j'],
['x,'y','z']
];
Notice how the inner arrays can have different length, which is where the term "jagged" comes from.
You can take advantages from OOP of ES6 :
class Matrix extends Array {
constructor(...rows) {
if(rows.some( r => !Array.isArray(r)))
throw new TypeError('Constructor accepts only rows as array')
super(...rows)
}
push(...rows) {
if(rows.some( r => !Array.isArray(r)))
throw new TypeError('Push method accepts array(s)')
super.push(...rows)
}
}
Use case 1:
Use case 2 :

Categories

Resources