JavaScript: Change all repeated values to 0 in array - javascript

I have an array with duplicate values
let ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
I want to set the repeated values to 0:
[0, 0, 0, 0, 7, 8, 0, 0, 2, 0, 6, 4, 0]
can find out the repeated value, but I want to change the repeated value to 0, is there any better way?
let ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
Array.prototype.duplicate = function () {
let tmp = [];
this.concat().sort().sort(function (a, b) {
if (a == b && tmp.indexOf(a) === -1) tmp.push(a);
});
return tmp;
}
console.log(ary.duplicate()); // [ 1, 3, 5, 9 ]
// ? ary = [0, 0, 0, 0, 7, 8, 0, 0, 2, 0, 6, 4, 0];

You could use indexOf() and lastIndexOf() method to solve your problem.
const array = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
const ret = array.map((x) =>
array.indexOf(x) !== array.lastIndexOf(x) ? 0 : x
);
console.log(ret);

const ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
// get set of duplicates
let duplicates = ary.filter((elem, index, arr) => arr.indexOf(elem) !== index)
duplicates = new Set(duplicates);
// set duplicate elements to 0
const res = ary.map(e => duplicates.has(e) ? 0 : e);
console.log(...res);

First, count values and store them in an object. Then loop over the array and check from that stored object whether the count of specific value is greater than 1 or not, if greater than 1, set that to 0. Here is the working example:
let ary = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
let countValue = {}, len = ary.length;
for (i = 0; i < len; i++) {
if (countValue[ary[i]]) {
countValue[ary[i]] += 1;
} else {
countValue[ary[i]] = 1;
}
}
for (i = 0; i < len; i++) {
if (countValue[ary[i]] > 1) {
ary[i] = 0;
}
}
console.log(...ary);

Probably this is the quickest algorithm, though it will alter your original array.
const array = [5, 1, 3, 5, 7, 8, 9, 9, 2, 1, 6, 4, 3];
const map = {};
for (let ind = 0; ind < array.length; ind++) {
const e = array[ind];
if (map[e] === undefined) {
map[e] = ind;
} else {
array[map[e]] = 0;
array[ind] = 0;
}
}
console.log(...array);

Related

Create a function to splice without using any built-in JavaScript methods

The code is working fine for all the test cases. Is it possible to reduce the number of lines of code or reduce the number of for loops?
const arr_splice = (arr, startIndex = 0, deleteCount = arr.length, ...insertElems) => {
// [1, 2, 3, 4, 5, 6]
for (let i = startIndex; i < arr.length; i++) {
arr[i] = arr[i + deleteCount]
}
// [ 1, 2, 5, 6, undefined, undefined ]
while (arr[arr.length - 1] == undefined && arr.length > 0) {
arr.length--
}
// [ 1, 2, 5, 6 ]
for (let i = arr.length - 1; i >= startIndex; i--) {
arr[i + insertElems.length] = arr[i]
}
// [ 1, 2, 5, 6, <2 empty items>, 5, 6 ]
for (let i = startIndex, j = 0; j < insertElems.length; j++, i++) {
arr[i] = insertElems[j]
}
// [1, 2, 10, 20, 30, 40, 5, 6]
return arr;
}
let result = arr_splice([1, 2, 3, 4, 5, 6], 2, 2, 10, 20, 30, 40);
console.log(result);//[1, 2, 10, 20, 30, 40, 5, 6]
//cross check
let arr=[1, 2, 3, 4, 5, 6]
arr.splice(2,2,10, 20, 30, 40)
console.log(arr);

Delete all elements from an array A which are present in an array B without using a double loop

So, as an input I have two arrays, A and B. Let's suppose that these are the values inside the two:
A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and B = [1, 3, 5, 7, 9]
After the deletion the array A should be [2, 4, 6, 8, 10].
I have written (Javascript) this functioning algorithm to solve this problem:
for (var i=0; i < A.length; i++) {
for (var j=0; j < B.length; j++) {
if(B[j] == A[i])
A.splice(i, 1) // Removes 1 element of the array starting from position i
}
}
I would like to know, is it possible to solve this problem without using a double loop?
What about this:
let A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ;
const B = [1, 3, 5, 7, 9];
A = A.filter(num => !B.includes(num));
Yes it is. You could use a Set. In terms of Set operations you are computing the difference A \ B.
Using a set which is optimized for lookups in O(1) time will speed up the computing the difference siginificantly from O(n²) when using includes() or double for loop to O(n).
const A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const B = [1, 3, 5, 7, 9]
const setB = new Set(B);
const difference = A.filter(x => !setB.has(x));
console.log(difference);
Maybe that ?
const
A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
, B = [1, 2, 3, 5, 7, 9] // no gaps in 1,2 and 2,3
;
for (let i =0, j=0 ; i < A.length; i++)
{
if (A[i]===B[j]) { A.splice(i--,1); j++ }
}
document.write( JSON.stringify(A) )
or (faster code)
const
A = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
, B = [ 1, 3, 5, 7, 9 ]
;
for (let i = A.length, j= B.length -1 ; i-- ; )
{
if (A[i]===B[j]) { A.splice(i,1); j-- }
}
document.write( JSON.stringify(A) )

JavaScript looping issue in the middle of looping

Hey guys I m trying to loop over the array of numbers, and what i want my function to do is whenever it is position of a number in array is EVEN number I want a program to return me 'Yan' word in stead of number. but when the position of a number is ODD number i want it to return just a number.
But for some reason in the middle of the array I am getting 'Yan' word instead of getting a number.
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
const reversValid1 = valid1.reverse()
const myArray = []
const validateCard = (arr) =>{
for(let i = 0; i < arr.length; i++){
if(arr.indexOf(reversValid1[i])%2 == 1){
console.log('Yan')
}
else{
console.log(arr[i])
}
}
}
validateCard(reversValid1)
I m getting the following response:
8
Yan
8
Yan
1
Yan
8
Yan
9
Yan
Yan
Yan
9
Yan
5
Yan
You can see i m getting 3 Yan consecutively.
Why instead of use indexOf don't use directly i ?
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
const reversValid1 = valid1.reverse()
const myArray = []
const validateCard = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (i % 2 == 1) {
console.log('Yan')
} else {
console.log(arr[i])
}
}
}
validateCard(reversValid1)
The problem is indexOf will find multiple index of same number.
Example:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
const reversValid1 = valid1.reverse()
for (let i = 0; i < reversValid1.length; i++) {
console.log(reversValid1[i], reversValid1.indexOf(reversValid1[i]))
}
As you can see the same number have same index instead of index of array.
You can use Array.forEach:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const reversValid1 = valid1.slice().reverse();
const validateCard = (arr) => {
arr.forEach((v,i)=>{
if (i%2 == 0) {
console.log('Yan');
} else {
console.log(v);
}
});
};
validateCard(reversValid1);
This might be what you want:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const reversValid1 = valid1.reverse();
const myArray = []
const validateCard = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
console.log('Yan');
}
else {
console.log(arr[i]);
}
}
}
validateCard(reversValid1);
Or this:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const reversValid1 = valid1.reverse();
const validateCard2 = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (i % 2 === 0) {
console.log('Yan');
}
else {
console.log(arr[i]);
}
}
}
validateCard2(reversValid1);

How object hash works to remove duplicates in this scenario?

function distinctUnion(arr, arr2) {
let merged = [...arr, ...arr2];
var result = [];
var map = {}
for (let i = 0; i < merged.length; i++) {
if (!map.hasOwnProperty(merged[i])) {
map[merged[i]] = true; // Line 3 --> if I remove this line, it prints duplicates
console.log('map', JSON.stringify(map, 2, null));
result.push(merged[i]);
}
}
return result;
}
let arr = [3, 4, 5, 6, 6, 4, 5, 8, 9, 10, 10];
let arr2 = [11, 11, 11, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6];
console.log('unique ', JSON.stringify(distinctUnion(arr, arr2), 2, null));
All we are setting here is map[merged[i]] = true; for all keys in object
map {"3":true,"4":true,"5":true,"6":true,"8":true,"9":true,"10":true,"11":true}
then how result.push(merged[i]) has only unique values?
I mean to say merged[i] inside loop should still have all array values including duplicates right?
I am not able to understand the link between map[merged[i]] = true; and result.push(merged[i])
If you do not set the property to anything, map.hasOwnProperty(...) will spuriously return false for the next time that value is encountered, thus allowing duplicates. You don't need to set it to true, as it is just used to indicate the presence of a key; any value is fine—even undefined!
function distinctUnion(arr, arr2) {
let merged = [...arr, ...arr2];
var result = [];
var map = {}
for (let i = 0; i < merged.length; i++) {
if (!map.hasOwnProperty(merged[i])) {
map[merged[i]] = undefined;
result.push(merged[i]);
}
}
return result;
}
let arr = [3, 4, 5, 6, 6, 4, 5, 8, 9, 10, 10];
let arr2 = [11, 11, 11, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6];
console.log('unique ', JSON.stringify(distinctUnion(arr, arr2), 2, null));
To make your code works, you just need to replace map[merged[i]] = true; with map[merged[i]] = undefined;.
However, you can make your function more simplified as follows:
function distinctUnion(arr, arr2) {
let map = {};
[...arr, ...arr2].forEach((x)=>{map[x] = x});
return Object.values(map);;
}
let arr = [3, 4, 5, 6, 6, 4, 5, 8, 9, 10, 10];
let arr2 = [11, 11, 11, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6];
console.log('Unique ', distinctUnion(arr, arr2));

javascript get the last duplicate value index javascript

I have an array to be like this var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5].
so it contains duplicate values. In here last index value of
'0' is '3',
'1' is '4',
'2' is '5',
'3' is '13', and so on.
And i counted total duplicate values
var counts = {};
arr.forEach(function(x) { counts[x] = (counts[x] || 0)+1; })
but i want to know last duplicate value index only. please help me.
thanks in advance
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var existingItems = {};
arr.forEach(function(value, index) {
existingItems[value] = index;
});
console.log(existingItems);
Simple loop and check to see if next index is different
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5]
var indexes = arr.reduce(function(result, cur, ind, arr){
if (ind+1===arr.length || cur != arr[ind+1]) { //check to see if last or different
result.push(ind); //if different, store the index
}
return result;
},[]);
console.log(indexes);
Array.prototype.lastIndexOf() comes in handy here:
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var out = {};
arr.forEach(function(item) {
if(!out.hasOwnProperty(item)) {
out[item] = arr.lastIndexOf(item);
}
});
console.log(out); // Object {0: 3, 1: 4, 2: 5, 3: 13, 4: 15, 5: 22}
This will also work for unsorted input arrays.
Well, what you can do is check if a value is a duplicate (count > 1) and then use the second parameter of forEach which is the index to remember it. Something like:
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var counts = {};
var indexes = {};
arr.forEach(function(x, idx) {
counts[x] = (counts[x] || 0) + 1;
if(counts[x] > 1) { indexes[x] = idx; } // check if a value is a duplicate and update its index
});
// logs the last index of all duplicate values
console.log(indexes); // {0: 3, 3: 13, 4: 15, 5: 22}
If you want the last index of all values, not just duplicates, you can omit the count > 1 check:
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var counts = {};
var indexes = {};
arr.forEach(function(x, idx) {
counts[x] = (counts[x] || 0) + 1;
indexes[x] = idx; // update value index
});
// logs the last index of all values
console.log(indexes); // {0: 3, 1: 4, 2: 5, 3: 13, 4: 15, 5: 22}

Categories