remove duplicates from a randomly selected array - javascript

I have the following code which tries to remove duplicates from a randomly selected array items but it did'nt work,
items[] is the array containing its and i have usea sript to remove duplicates.
how do i change it to remove duplicates
what is the mistake?
window.onload = rnumber();
function rnumber() {
const
items = [
{ label: '1', url: '1.jpg' },
{ label: '2', url: '2.jpg' },
{ label: '3', url: '3.jpg' },
{ label: '4', url: '4.jpg' },
{ label: '5', url: '5.jpg' },
{ label: '6', url: '6.jpg' },
{ label: '7', url: '7.jpg' },
{ label: '8', url: '8.jpg' },
{ label: '9', url: '9.jpg' },
{ label: '10',url: '10.jpg' }
];
var lastnumber=0;
for (let index = 0; index < 9; index++)
{
randomIndex = Math.floor(Math.random() * items.length);
if(lastnumber!=randomIndex)
{
item = items[randomIndex];
lastnumber=randomIndex;
console.log(randomIndex);
}
else
{
rnumber()
}
}
}

You can use reduce to get rid of duplicates
const distinctShuffle = array =>
array ? array.reduce((arr, item) => {
if (!(item in arr)) {
arr.splice(Math.floor(Math.random() * (arr.length + 1)), 0, item);
}
return arr;
}, []) : array;
function rnumber() {
const items = [
{ label: '1', url: '1.jpg' },
{ label: '2', url: '2.jpg' },
{ label: '3', url: '3.jpg' },
{ label: '4', url: '4.jpg' },
{ label: '5', url: '5.jpg' },
{ label: '6', url: '6.jpg' },
{ label: '7', url: '7.jpg' },
{ label: '8', url: '8.jpg' },
{ label: '9', url: '9.jpg' },
{ label: '10',url: '10.jpg' }
];
return distinctShuffle(items);
}
console.log(rnumber());

You have some syntax errors in your code. Watch out for using semicolons at the end of the statement - not commas.
If you're using ES6 you can write something like this:
let distinct = [...new Set(items.map(item => item.label))]

Use Following Simple Function to Remove Duplicates from array using jquery
var YourArray = [
{ label: '1', url: '1.jpg' },
{ label: '1', url: '2.jpg' },
{ label: '3', url: '3.jpg' },
{ label: '4', url: '4.jpg' },
{ label: '1', url: '5.jpg' },
{ label: '6', url: '6.jpg' },
{ label: '1', url: '7.jpg' },
{ label: '8', url: '8.jpg' },
{ label: '9', url: '9.jpg' },
{ label: '10',url: '10.jpg' }
];
var SortedArray = YourArray.filter(
function(a){if (!this[a.label]) {this[a.label] = 1; return a;}},
{}
);
alert(JSON.stringify(SortedArray));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Array data is getting replaced inside forEach nested with map in JavaScript/TypeScript

Why 1st iteration data is getting replaced in 2nd iteration?
Is there any other simpler method in ES6 to achieve this?
a = [
{ name: 'NameOne', weekName: 'WeekOne' },
{ name: 'NameTwo', weekName: 'WeekTwo' },
];
b = [
{ id: 'Name', type: 'text', data: '' },
{ id: 'Week', type: 'text', data: '' },
];
c = [];
showOutput() {
this.a.forEach((element) => {
this.b.map((item) => {
if (item.id == 'Name') {
item.data = element.name;
}
if (item.id == 'Week') {
item.data = element.weekName;
}
this.c.push(item);
console.log('c', this.c);
});
});
}
Current Output :
[{ id: 'Name', type: 'text', data: 'NameTwo' },
{ id: 'Week', type: 'text', data: 'WeekTwo' },
{ id: 'Name', type: 'text', data: 'NameTwo' },
{ id: 'Week', type: 'text', data: 'WeekTwo' }]
Desired Output:
[{ id: 'Name', type: 'text', data: 'NameOne' },
{ id: 'Week', type: 'text', data: 'WeekOne' },
{ id: 'Name', type: 'text', data: 'NameTwo' },
{ id: 'Week', type: 'text', data: 'WeekTwo' }]
Problem with your code is that this.c.push(item); here the same object is getting referenced so in 2nd iteration it's changing the data that modified by 1st iteration. In order to solve this, you will have to clone the object (dereference somehow)
I have used c.push(Object.assign({}, item)); or you can use c.push(JSON.parse(JSON.stringify(item))); or any other way to clone the object before pushing into array (c in your case)
Note: This is just to point out the root cause of the issue, and it may not be the perfect solution for your scenario.
e.g.
a = [
{ name: 'NameOne', weekName: 'WeekOne' },
{ name: 'NameTwo', weekName: 'WeekTwo' },
];
b = [
{ id: 'Name', type: 'text', data: '' },
{ id: 'Week', type: 'text', data: '' },
];
c = [];
function showOutput() {
a.forEach((element) => {
b.map((item) => {
if (item.id == 'Name') {
item.data = element.name;
}
if (item.id == 'Week') {
item.data = element.weekName;
}
c.push(Object.assign({}, item)); // clone object
});
});
}
showOutput();
console.log('c', c);
For more information: https://javascript.info/object-copy

Looping array of object into array of object javascript

so i have two arrays of object like this:
var lab =[
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 }
];
var val = [ { label: '1', value: 42 },
{ label: '2', value: 55 },
];
lab.forEach(labs=>{
val.forEach(vals=>{
labs["columns"]=vals.value
})
})
console.log(lab)
i try to get the value like this
[ { label: '1', value: 42, columns: {42,55} },
{ label: '2', value: 55, columns:{42,55} },
{ label: '3', value: 51, columns: {42,55} },
{ label: '4', value: 22, columns: {42,55} } ]
but after i ran the code i get the value that i am not wanted like this:
[ { label: '1', value: 42, columns: 55 },
{ label: '2', value: 55, columns: 55 },
{ label: '3', value: 51, columns: 55 },
{ label: '4', value: 22, columns: 55 } ]
where do i did wrong actually on the loop..
Does this do what you want?
const lab = [
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 },
];
const val = [
{ label: '1', value: 42 },
{ label: '2', value: 55 },
];
// we get an array of stuff that the OP wants to add,
// as apparently it is identical for each object.
const columns = val.map(obj => obj.value);
const a = lab.map(labs => {
return {
// shallow copys for every item.
...labs,
columns: [...columns],
};
});
console.log({ a });
.as-console-wrapper { min-height: 100%!important; top: 0; }
map array method takes a function returns a new array where each element was updated by calling that function with element as it's argument.
This answer uses two calls of map, same amount as your answer, however in your answer map calls are nested, so the inner map would be called for each element, while it's result will be always the same, in my answer we call it once.
i have figured it out by using map function
var lab =[
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 }
];
var val = [ { label: '1', value: 10 },
{ label: '2', value: 55 },
];
const a = lab.map((labs)=>{
let ab={
label:labs.label,
value:labs.value,
columns:val.map((vals)=>{
return vals.value
})
}
return ab
})
console.log(a)
hope it will help

JS merge two subarray using map

I use the following to merge two arrays:
var mySeries = [
{ name: '4', data: [4] },
{ name: '3', data: [3] }
];
var mySeries1 = [
{ name: '5', data: [0] },
{name: '4', data:[0]},
{name: '3', data:[0]},
{name: '2', data:[0]},
{ name: '1', data: [0] }
];
var res = mySeries1.map(obj => mySeries.find(o => o.name === obj.name) || obj);
console.log(res);
Works great; however, my challenge is my array is structured as:
var myArray = [{
mySeries : [
{ name: '4', data: [4] },
{ name: '3', data: [3] }],
mySeries1 : [
{ name: '5', data: [0] },
{ name: '4', data: [0] },
{ name: '3', data: [0] },
{ name: '2', data: [0] },
{ name: '1', data: [0] }]
}];
];
So I need to map subarrays, tried using the following:
var res = myArray.mySeries1.map(obj => myArray.mySeries.find(o => o.name === obj.name) || obj);
I get this error:
Cannot read properties of undefined (reading 'map')
How can I point to the subarray?
var myArray = [{
mySeries : [
{ name: '4', data: [4] },
{ name: '3', data: [3] }],
mySeries1 : [
{ name: '5', data: [0] },
{ name: '4', data: [0] },
{ name: '3', data: [0] },
{ name: '2', data: [0] },
{ name: '1', data: [0] }
]
}];
var res = myArray[0].mySeries1.map(obj => myArray[0].mySeries.find(o => o.name === obj.name) || obj);
console.log(res)
you could change your array to dictionary and iterate it like you already did.
var myArray = {
mySeries : [
{ name: '4', data: [4] },
{ name: '3', data: [3] }],
mySeries1 : [
{ name: '5', data: [0] },
{ name: '4', data: [0] },
{ name: '3', data: [0] },
{ name: '2', data: [0] },
{ name: '1', data: [0] }]
};
i.e. var res = myArray.mySeries1.map(obj => myArray.mySeries.find(o => o.name === obj.name) || obj);

How to find the count of particular object in array using javascript?

I have an array of objects like below:
const arr_obj = [
{
id: '1',
children: [],
type: 'TYPE1',
},
{
id: '2',
children: [
{
id: '1',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '2',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '3',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
]
type: 'TYPE2',
},
{
id: '3',
children: [
{
id: '4',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '5',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '6',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
]
type: 'TYPE2',
}
]
I have to find out the count of type: 'MAIN'. these 'MAIN' will be within type: "type2"
So the expected count is 6. The outer children array can be empty and sometimes inner children array with type: "type2" is not there at all examples like below:
children: [] //empty array
children: [
{
id: '1',
children: [],
type: 'TYPE1',
},
] //no children with type: 'TYPE2'
Could someone help me with this? New to programming.
EDIT:
what i have tried?
const findAllChildrenOfType = (obj, type) => {
let count = 0;
if (obj.type === type) count++;
if (obj.children) {
obj.children.forEach(child => {
const childCount = findAllChildrenOfType(child,
"MAIN");
count += childCount;
})
}
return count;
}
findAllChildrenOfType(arr_obj, "TYPE2");
But this gives me count always 0.
const arr_obj = [
{
id: '1',
children: [],
type: 'TYPE1',
},
{
id: '2',
children: [
{
id: '1',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '2',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '3',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
],
type: 'TYPE2',
},
{
id: '3',
children: [
{
id: '4',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '5',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '6',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
],
type: 'TYPE2',
}
];
let count = 0
const findAllChildrenOfType = (obj, type) => {
if (obj?.type === type) count++;
if(obj?.children?.length) {
obj.children.forEach((child) => {
findAllChildrenOfType(child, type);
});
}
// return count;
};
arr_obj.forEach((child) => {
if(child.type === 'TYPE2') {
findAllChildrenOfType(child, "MAIN");
}
});
console.log(count);
You could create a small function inside your findAllChildrenOfType() function, that will iterate over the array, and increment the count if it encounters an object with given type. Then you can return the count from the parent function, by subtracting the number of objects with initial type ("TYPE2" in this case), since they also get added up, when you increment the count in if(obj.type === type).
const arr_obj=[{id:"1",children:[],type:"TYPE1"},{id:"2",children:[{id:"1",children:[{}],type:"MAIN"},{id:"2",children:[{}],type:"MAIN"},{id:"3",children:[{}],type:"MAIN"}],type:"TYPE2"},{id:"3",children:[{id:"4",children:[{}],type:"MAIN"},{id:"5",children:[{}],type:"MAIN"},{id:"6",children:[{}],type:"MAIN"}],type:"TYPE2"}];
const findAllChildrenOfType = (arr_obj, type) => {
let count = 0;
let findElem = (arr_obj, type) => {
arr_obj.forEach(obj => {
if (obj.type === type) {
count++;
if (obj.children.length) {
return findElem(obj.children, "MAIN");
}
}
});
return count;
}
count = findElem(arr_obj, type);
let fil = arr_obj.filter(obj => obj.type === type).length;
return count - fil;
}
console.log(findAllChildrenOfType(arr_obj, "TYPE2"));
A small recursive loop.
const data=[{id:"1",children:[],type:"TYPE1"},{id:"2",children:[{id:"1",children:[{}],type:"MAIN"},{id:"2",children:[{}],type:"MAIN"},{id:"3",children:[{}],type:"MAIN"}],type:"TYPE2"},{id:"3",children:[{id:"4",children:[{}],type:"MAIN"},{id:"5",children:[{}],type:"MAIN"},{id:"6",children:[{}],type:"MAIN"}],type:"TYPE2"}];
const data2=[{id:"1",children:[],type:"TYPE1"},{id:"2",children:[{id:"1",children:[{}],type:"MAIN"},{id:"2",children:[{}],type:"MAIN"},{id:"3",children:[{}],type:"MAIN"}],type:"TYPE2"},{id:"3",children:[{id:"4",children:[{}],type:"MAIN"},{id:"5",children:[{}],type:"MAIN"},{id:"6",children:[{}],type:"MAIN"},{id:"7",children:[{}],type:"MAIN"},{id:"8",children:[{}],type:"MAIN2"}],type:"TYPE2"}];
function find(arr) {
let count = 0;
function loop(arr) {
for (const obj of arr) {
const { type, children } = obj;
if (type === 'TYPE2') loop(children);
if (type === 'MAIN') ++count;
}
}
loop(arr);
return count;
}
console.log(find(data));
console.log(find(data2));
Instead of use it with all object i use forEach and use function for each object like:
const arr_obj = [{
id: '1',
children: [],
type: 'TYPE1',
},
{
id: '2',
children: [{
id: '1',
children: [{
//some attributes
}],
type: 'MAIN',
},
{
id: '2',
children: [{
//some attributes
}],
type: 'MAIN',
},
{
id: '3',
children: [{
//some attributes
}],
type: 'MAIN',
},
],
type: 'TYPE2',
},
{
id: '3',
children: [{
id: '4',
children: [{
//some attributes
}],
type: 'MAIN',
},
{
id: '5',
children: [{
//some attributes
}],
type: 'MAIN',
},
{
id: '6',
children: [{
//some attributes
}],
type: 'MAIN',
},
],
type: 'TYPE2'
}
];
const findAllChildrenOfType = (obj, type) => {
let count = 0;
if (obj.type === type) {
if (type === 'MAIN') count++;
if (obj.children) {
obj.children.forEach(child => {
const childCount = findAllChildrenOfType(child,
"MAIN");
count += childCount;
})
}
}
return count;
}
let countAll = 0;
arr_obj.forEach(el => {
countAll += findAllChildrenOfType(el, "TYPE2");
});
console.log(countAll)

Javascript filter method, Remove all Items with matching values in array

I'm trying to remove all items if they match with array values but it's removing only one item. How can i remove all items with filter method or what is the best way to achieve this.
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
data = data.filter(post => {
let remove = ['2', '4', '5']
for(let i = 0; i < remove.length; i++) {
return post.id !== remove[i]
}
})
console.log(data)
Thanks
you should return false if you want to remove item from array
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
let remove = ['2', '4', '5']
data = data.filter(post => {
return !remove.includes(post.id);
})
console.log(data)
All the notice are in the snippet's comment
let data = [ { id: '1', title: 'ABC' }, { id: '2', title: 'DEF' }, { id: '3', title: 'GHI' }, { id: '4', title: 'JKL' }, { id: '5', title: 'MNO' } ]
const remove = ['2', '4', '5']
// `indexOf` is from ES5
data = data.filter(post => remove.indexOf(post.id) === -1)
console.log(data)
// `includes` is from ES7
data = data.filter(post => !remove.includes(post.id))
console.log(data)
// this will recreate the array ['2', '4', '5'] 5 times
data = data.filter(post => !['2', '4', '5'].includes(post.id))
console.log(data)
There is no need to use for loop inside of filter.
Instead it is possible to use some method inside of filter. The some method checks whether at least one element satisfies condition inside of provided function. So unnecessary iteration will be avoided:
data.filter(f => !remove.some(s => s == f.id))
An example:
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
let remove = ['2', '4', '5']
console.log(data.filter(f => !remove.some(s => s == f.id)));
I'll suggest using includes rather then a nested for loop.
You should also move the remove var outside of the loop, so it's not reinitialised every time.
The callback to the filter method is a predicate. If the condition evaluates to true, the current value in the iteration will be returned. In your case, you want to return if the current value is not in the remove array.
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
const remove = ['2', '4', '5']
data = data.filter(post => {
return !remove.includes(post.id)
})
console.log(data)

Categories