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));
Related
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);
I don't understand this method of pop and unshift in this array
let nums = [1, 2, 3, 6, 9, 8, 7, 4];
const ids = [1, 2, 3, 6, 9, 8, 7, 4];
let btn5 = document.getElementById("btn5");
btn5.onclick = function() {
nums.unshift(nums.pop());
for (i = 0; i <= 7; i++) {
document.getElementById("btn" + ids[i]).innerHTML = nums[i];
}
}
nums.unshift(nums.pop()); is:
// Remove the last entry from the array
const tmp = nums.pop();
// Insert it at the beginning of the array
nums.unshift(tmp);
So for instance, the first time that runs, nums starts with:
[1, 2, 3, 6, 9, 8, 7, 4]
so pop removes the 4 from the end, and inserts it at the beginning:
[4, 1, 2, 3, 6, 9, 8, 7]
Live Example:
const nums = [1, 2, 3, 6, 9, 8, 7, 4];
console.log("before:", JSON.stringify(nums));
nums.unshift(nums.pop());
console.log("after: ", JSON.stringify(nums));
Details on MDN: pop, unshift.
Array pop method removes and return last element of an array. If you write something like,
let nums = [1, 2, 3, 6, 9, 8, 7, 4];
const ids = [1, 2, 3, 6, 9, 8, 7, 4];
const poppedValue = nums.pop(); //poppedValue = 4 and nums = [1, 2, 3, 6, 9, 8, 7]
And unshift method push the item at the beginning of the array.
nums.unshift(poppedValue); // nums = [4, 1, 2, 3, 6, 9, 8, 7];
I have 2 arrays, one has 10 elements and the other one 3, I need to create a new array with the same size of the biggest vector, with a boolean checking true in the position where exist some element from the array of 3 elements
I have the following arrays
array1 = [1,2,3,4,5,6,7,8,9,10]
array2 = [4,6,10]
I tried making 2 for loops
for(var i=0; i<array1.lenght; i++){
for(var j=0; i<array2.lenght; i++){
if(array1[i]==array2[j]){
array3.push(true)
}else{
array3.push(false)
}
}
}
the vector that I need would be
array3 = [false, false, false, true, false, true, false, false, false, true]
You can forEach first array and use include method to check if item existed in array as
let array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let array2 = [4, 6, 10];
let array3 = [];
array1.forEach(function (c) {
if (array2.includes(c)) {
array3.push(true)
} else {
array3.push(false);
}
})
console.log(array3)
Use map like so with shift like so:
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const array3 = array1.map(e => {
if (array2[0] == e) {
array2.shift();
return true;
}
return false;
});
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: auto; }
If you just want a basic check as for whether the element is in the array, not the order, then use includes.
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const array3 = array1.map(e => array2.includes(e));
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: auto; }
You can also instead of another array use a Set and then Array.map the first away checking if the value is in the Set:
let array1 = [1,2,3,4,5,6,7,8,9,10],
set = new Set([4,6,10])
let result = array1.map(x => set.has(x))
console.log(result)
I would suggest to keep things simple and to use Array#indexOf method to determine if array contains another element.
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const b = array1.map(el => {
return array2.indexOf(el) !== -1;
});
console.log(b);
const array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const array2 = [4, 6, 10];
const finalArray = [];
for (let data of array1) {
finalArray.push(array2.includes(data));
}
So I have an array of ids something like this:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
I need a function that will be called like mergeArray(arr, 3), and it should return comma separated values with maximum of 3 elements like this:
const newArr = ['1,2,3', '4,5,6', '7,8,9', '10,11'];
How can I do this? If possible with ES6 functions for simpler code.
slice your array into 3 lengths arrays and directly join them
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
const mergeArray = (arr, size) => {
let res = [];
for (i = 0; i < arr.length; i += size) {
res.push(arr.slice(i, i + size).join(','));
}
return res;
}
console.log(mergeArray(arr, 3));
You can split() the array into the specific size and join() them before pushing into the resulting array:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
var i, j, newArr=[], size = 3;
for (i=0,j=arr.length; i<j; i+=size) {
newArr.push(arr.slice(i, i+size).join());
}
console.log(newArr);
One of the ways to do it is with Array.prototype.reduce and Array.prototype.map:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
function mergeArray(arr, n) {
return arr
.reduce((all, el, i) => {
const ind = Math.floor(i/n);
all[ind] = [...all[ind] || [], el]
return all;
},[])
.map(a => a.join(','))
}
console.log(mergeArray(arr, 3));
You could join the array and match the wanted parts with a regular expression.
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
result = data.join(',').match(/\d+(,\d+(,\d+)?)?/g)
console.log(result);
I have an array of arrays
[
[1,3,5,7,8,8],
[1,3,5,7,8,8],
[1,3,5,7,8,8],
[1,3,5,7,8,8],
[1,3,5,7,8,8]
]
I am trying to insert a value between each item. So I have this:
let reelList = [
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8]
]
reelList.map(reel => {
// Adds the separator (works)
let v = separate(reel, '-')
console.log(v)
return v
})
function separate(arr, value) {
return arr.reduce((result, element, index, array) => {
result.push(element)
index < array.length - 1 && result.push(value)
return result
}, []);
}
// Logs the new list to the console (doesn't work)
console.log(reelList)
When I log the values after I run the separate function they are separated, however, when I display reelList they are not separated. Why is that?
The map() function returns a new array. It doesn't modify the existing one.
You would need to set the results of reelList.map() to something else.
let reelList = [
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8]
]
const finalResult = reelList.map(reel => {
// Adds the separator (works)
let v = separate(reel, '-')
console.log(v)
return v
})
function separate(arr, value) {
return arr.reduce((result, element, index, array) => {
result.push(element)
index < array.length - 1 && result.push(value)
return result
}, []);
}
// Logs the new list to the console (doesn't work)
console.log(finalResult);
If you want to edit the array in place, instead of using map(), use a forEach() with a callback that has a second and third parameter, which are index and array. Then you can update the array with the new values as you go.
let reelList = [
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8],
[1, 3, 5, 7, 8, 8]
]
reelList.forEach((reel, index, arr) => {
// Adds the separator (works)
let v = separate(reel, '-')
arr[index] = v;
console.log(v)
})
function separate(arr, value) {
return arr.reduce((result, element, index, array) => {
result.push(element)
index < array.length - 1 && result.push(value)
return result
}, []);
}
// Logs the new list to the console (doesn't work)
console.log(reelList);
You could map a new array with a calculated lenght and take the result of the calculated index ot the dash.
var array = [[1, 3, 5, 7, 8, 8], [1, 3, 5, 7, 8, 8], [1, 3, 5, 7, 8, 8], [1, 3, 5, 7, 8, 8], [1, 3, 5, 7, 8, 8]],
result = array.map(a => Array.from({ length: a.length * 2 - 1 }, (_, i) => a[i / 2] || '-'));
console.log(result);