get 2 array unique and duplicate elements from parent array - javascript

let array=[1,1,2,3,4,4,5,5,6,6,7,8]:
I want to get 2 array of unique and duplicate elements: duplicate element's array1:[1,4,5,6] unique element's array2:[2,3,7,8]
Help is very much appreciated.

Simply use a map to filter out duplicates. Here's a working solution.
let arr= [1,1,2,3,4,4,5,5,6,6,7,8];
function uniqueAndDuplicates() {
var obj = {};
var duplicates = [];
var noDup = [];
for(var i = 0; i < arr.length; i++){
if(!obj[arr[i]]){
obj[arr[i]] = 1;
noDup.push(arr[i]);
} else {
duplicates.push(arr[i]);
}
}
var unique = noDup.filter(function(item, index){
if(!duplicates.includes(noDup[index])){
return noDup[index];
}
});
return {
unique,
duplicates
}
}
console.log(uniqueAndDuplicates(arr));

One solution is you can create a freq map and then you can essentially create an Array from that map then filter out the counts greater than 1 and less than 1.
let array=[1,1,2,3,4,4,5,5,6,6,7,8]
const returnUniqueAndDuplicateElements = (arr) => {
let freqMap = {};
for(const idx in arr){
let number = arr[idx];
if(!freqMap[number]){
freqMap[number]=0;
}
freqMap[number]++;
}
const entries = Object.entries(freqMap);
return {
unique: entries.filter(([, freq]) => freq <= 1).map(item => Number(item[0])),
duplicates: entries.filter(([, freq]) => freq > 1).map(item => Number(item[0]))
}
}
console.log(returnUniqueAndDuplicateElements(array))

I am adding my solution since there is none with JS sets[?] just yet:
function uniqueAndDuplicate(arrayOfNumbers) {
const unique = new Set();
const duplicate = new Set();
arrayOfNumbers.forEach((elem) => {
if (unique.has(elem)) {
unique.delete(elem);
duplicate.add(elem);
} else if (!duplicate.has(elem)) {
unique.add(elem);
}
});
return {
unique: [...unique],
duplicate: [...duplicate],
};
}
console.log(uniqueAndDuplicate([1,1,2,3,4,4,5,5,6,6,7,8]));

Related

Divide an array into subarray depending on string and join its items. Javascript

I would like to transform an array into another separing its items depending on a string data, and, when there are two or more items together and none of them is is the limit string data i would like to join then by "/". Something like this:
const stringLimit = "aa";
let arrayData =["b","c","aa","aa","d","c","aa","f"];
result:
arrayResult=["b/c","d/c","f];
I have try this, however, I think that there should be a better way
let stringItem;
let totalRouteDevice = new Array();
for (let index = 0; index < arrayData.length; index++) {
const item = arrayData [index];
if(item!=='aa' && item !== 'bb') {
stringItem = stringItem!=""?`${stringItem}/${item}`:stringItem
} else if(stringRouteItem!=="") {
totalRoute.push(stringItem);
stringItem ="";
}
}
I have try this, however, I think that there should be a better way
let stringItem;
let totalRouteDevice = new Array();
for (let index = 0; index < arrayData.length; index++) {
const item = arrayData [index];
if(item!=='aa' && item !== 'bb') {
stringItem = stringItem!=""?`${stringItem}/${item}`:stringItem
} else if(stringRouteItem!=="") {
totalRoute.push(stringItem);
stringItem ="";
}
}
Not saying this is better but you could group your data using reduce, splitting it by stringLimit, and then joining the groups by / as follows:
const stringLimit = 'aa'
const arrayData = ["b","c","aa","aa","d","c","aa","f"]
let arr = []
arrayData.reduce((acc, item, i) => {
if (item !== stringLimit) {
acc.push(item)
} else {
if (acc.length) {
arr.push(acc)
}
acc = []
}
if (item !== stringLimit && i === arrayData.length - 1) {
arr.push(acc)
}
return acc
}, [])
let result = arr.map((i) => i.join('/'))
console.log(result)

How do I remove multiple elements from an array?

I want to write a function that passes an array and an optional number of values to be removed from the array as parameters. My function works when there is only 1 value, but fails when there is multiple values.
const removeFromArray = function (arr, ...theArgs) {
for (let i = 0; i < arr.length; i++) {
if (theArgs.includes(arr[i])) {
arr.splice(i, 1);
}
}
return arr;
};
You can use the filter method for that:
const removeFromArray = function (arr, ...theArgs) {
return arr.filter( val => !theArgs.includes(val) )
};
const list = [1,2,3];
const newList = removeFromArray(list, 2,3);
console.log(newList);
And a more terse version:
const removeFromArray = (arr, ...args)=> arr.filter( val => !args.includes(val) )
Tip: try to avoid mutating the original array and work on or return a copy during these operations.
The issue is with your indexing, you are finding the element using the index of arr, and deleting in the array, which is probably causing issue with indexing in loop.
Modify your code as follows
const removeFromArray = function (arr, ...theArgs) {
for (let i = 0; i < theArgs.length; i++) {
if (arr.includes(theArgs[i])) {
arr.splice(arr.indexOf(theArgs[i]), 1);
}
}
return arr;
};
The above fixes the code your way, but a better way of doing it would be using filter.
const removeFromArray = function (arr, ...theArgs) {
return arr.filter(ele => !theArgs.includes(ele))
}
I am writing it this way to purely maintain your function.
The problem is because you remove item from the array while being looping from that array.
Every time your for loop iterate the array, it will get a new array
e.g. (1,2,3,4,5 => 2,3,4,5), but the i value just keeping increasing by 1.
const removeFromArray = function (arr, ...theArgs) {
for (let i = 0; i < arr.length; i++) {
console.log(`arr:${arr}`,`item${arr[i]}`,`num${i}`)
console.log(arr[i])
if (theArgs.includes(arr[i])) {
arr.splice(i, 1);
}
}
return arr;
};
const testarray = [1,2,3,4,5]
console.log(removeFromArray(testarray,1,2,3))
I would suggest to use array as a second parameter.
var array1 = ['a','b','c'];
var elementsToRemove = ['a','b'];
const removeFromArray = function (array1, elementsToRemove) {
var filtered = array1.filter(function(value, index, array){
return elementsToRemove.includes(value);
});
return filtered;
}
console.log(removeFromArray(array1,elementsToRemove));

Remove Duplicate Object from JSON Array

I am trying to remove duplicate JSON Objects from the array in ServiceNow.
Tried below code but it does not remove the duplicate. I want to compare both name & city.
var arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
var splitlen = JSON.parse(arr1);
alert(splitlen.length);
var uniqueArray = [];
var uniqueJson = {};
for(i=0;i<splitlen.length;i++)
{
if(uniqueArray.indexOf(splitlen[i].name)==-1)
{
uniqueArray.push(splitlen[i]);
}
}
alert(JSON.stringify(uniqueArray));
Expected output :
[{"name":"Pune","city":"India"}]
uniqueArray.indexOf doesn't work because you're comparing objects against strings (splitlen[i].name). Try to use .find() instead:
var arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
var splitlen = JSON.parse(arr1);
var uniqueArray = [];
var uniqueJson = {};
for(i=0;i<splitlen.length;i++)
{
if(!uniqueArray.find(x => x.name === splitlen[i].name))
{
uniqueArray.push(splitlen[i]);
}
}
console.log(uniqueArray);
or
var arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
var splitlen = JSON.parse(arr1);
function compare(x){
return x.name === splitlen[i].name;
}
var uniqueArray = [];
var uniqueJson = {};
for(i=0;i<splitlen.length;i++)
{
if(!uniqueArray.find(compare))
{
uniqueArray.push(splitlen[i]);
}
}
console.log(uniqueArray);
you can try this. Also one more thing your array declaration is not right, remove single quotes from array.
var arr1 = [{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}];
function getUniqueListByKey(arr, key) {
return [...new Map(arr.map(item => [item[key], item])).values()]
}
var arr2 = getUniqueListByKey(arr1, "name")
console.log(arr2);
Please try the following example
const arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
const splitlen = JSON.parse(arr1);
const output = splitlen.reduce((previousValue, currentValue) => {
const { name, city } = currentValue;
const index = previousValue.findIndex(
(entry) => entry.name === name && entry.city === city
);
if (index === -1) {
return [...previousValue, currentValue];
}
return previousValue;
}, []);
console.log(output);
See
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
Put the records in a hashset. If there is collision in the hashset, there is duplicate. This approach is O(n) while comparing all pairs is $O(n^2)$.
I'm trying to get an answer, here's my idea:
Create a function to compare two objects then create a function to get the unique value
function isEquals(obj1, obj2) {
const aProps = Object.getOwnPropertyNames(obj1);
const bProps = Object.getOwnPropertyNames(obj2);
if (aProps.length !== bProps.length) {
return false;
}
for (let j = 0; j < aProps.length; j++) {
const propName = aProps[j];
if (JSON.stringify(obj1[propName]) !== JSON.stringify(obj2[propName])) {
return false;
}
} return true;
}
function getUnique(arr) {
var uniqueArray = [];
for (var item of arr) {
const uniqueItems = arr.filter(i => isEquals(item, i));
if (uniqueItems.length !== 0) {
uniqueArray.push(Object.assign({}, uniqueItems.shift()));
}
arr = arr.filter(i => !isEquals(item, i));
}
return uniqueArray;
}
Hope it helps!

How do I manipulate a value of an array in javascript?

I'm quite new to Javascript and I have the following javascript array in an AJAX Request that contains the following:
["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"]
I wanna manipulate the TRUE and FALSE value. If they're in uppercase, I want to make it lowercase. Any idea how I can do it?
If you want to modify the list you could just loop through all of its items, modify the value and set it to the same index of the list. (You don't need to set it if you are dealing with objects).
var list = ["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"];
list.forEach(function(item, index) {
list[index] = item.replace(/(TRUE|FALSE)/g, function(upperCase) {
return upperCase.toLowerCase();
});
});
console.log(list);
Same thing using a for loop:
var list = ["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"];
for (var index = 0; index < list.length; index++) {
list[index] = list[index].replace(/(TRUE|FALSE)/g, function(upperCase) {
return upperCase.toLowerCase();
});
}
console.log(list);
If you want to create a copy you could do:
var list = ["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"];
var newList = list.map(function(item) {
return item.replace(/(TRUE|FALSE)/g, function(upperCase) {
return upperCase.toLowerCase();
});
});
console.log(newList);
The above scripts will also transform something like ["THIS IS NOT TRUE|TRUE|FALSE"] to ["THIS IS NOT true|true|false"]. If you do not want that you should use this regex instead /(^|(?<=\|))(TRUE|FALSE)(\||$)/ i.e.:
var list = ["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRowFALSE|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"];
for (var index = 0; index < list.length; index++) {
list[index] = list[index].replace(/(^|(?<=\|))(TRUE|FALSE)(\||$)/g, function(upperCase) {
return upperCase.toLowerCase();
});
}
console.log(list);
Just use replace with map:
const arr = ["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"];
const res = arr.map(e => e.replace(/(TRUE|FALSE)/g, m => m.toLowerCase()));
console.log(res);
const arrayString = ["12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE"]
const arrayOfValues = arrayString[0].split('|').map(val => {
if(val === 'TRUE' || val === 'FALSE') {
return val.toLowerCase();
} else {
return val;
}
});
console.log(arrayOfValues)
Use RegEx as you have been told before.
If you want to learn more about this look at: W3Schools
One solution could be like this:
var ajaxResponse = "12435|#CANON#DEVICE#|#50#|Machine Detail|Details|SampleRow|FALSE|FALSE|FALSE|FALSE|FALSE|FALSE|TRUE";
ajaxResponse = ajaxResponse.replace(/FALSE/g, "false");
ajaxResponse = ajaxResponse.replace(/TRUE/g, "true");
console.log(ajaxResponse);

Javascript remove duplicated object from array

i'm having trouble to remove duplicated object from my array
example:
var list = [{place:"AAA",name:"Me"}, {place:"BBB",name:"You"}, {place:"AAA",name:"Him"}];
in this example i have 3 objects, and i want to remove the object that have the duplicated place
Just in case someone wonders: underscore.js solution:
var list = [{place:"AAA",name:"Me"}, {place:"BBB",name:"You"}, {place:"AAA",name:"Him"}];
_.uniq(list, function(item, key, a) {
return item.place;
})
Example Fiddle
A simple one:
var list = [{place:"AAA",name:"Me"}, {place:"BBB",name:"You"}, {place:"AAA",name:"Him"}];
list.forEach(function(i) {
var duplicates = list.filter(function(j) {
return j !== i && j.place == i.place;
});
duplicates.forEach(function(d) { list.splice(list.indexOf(d), 1); });
});
// list = [{place:"AAA",name:"Me"}, {place:"BBB",name:"You"}];
document.write(JSON.stringify(list));
As you added:
i want to remove just one, dont matter wich one
If you want to remove duplicated items and keep only the first occcurence of particular place, you can simply use a simple loop to re-create a new array from the input:
var list = [{place:"AAA",name:"Me"}, {place:"BBB",name:"You"}, {place:"AAA",name:"Him"}];
var uniqPlace = function(array){
var result = [];
array.forEach(function(el){
if (result.filter(function(n){ return n.place === el.place }).length==0){
result.push(el);
}
})
return result;
}
Output:
uniqPlace(list);
[{"place":"AAA","name":"Me"},{"place":"BBB","name":"You"}]
Try this.
var result = {};
for (i = 0, n = arr.length; i < n; i++) {
var item = arr[i];
result[ item.place + " - " + item.name ] = item;
}
Loop the result again, and recreate the array.
i = 0;
for(var item in result) {
clearnArr[i++] = result[item];
}
Create a object to store the items by their place value, as the new item with the same key will overwrite the old one, this will easily remove all dulplicates.
var list = [{place:"AAA",name:"Me"}, {place:"BBB",name:"You"}, {place:"AAA",name:"Him"}];
var removeDuplicate = function(list) {
var keyStore = {};
var output = [];
// If you want to creata totally new one from old, use
// list = JSON.parse(JSON.stringify(list));
// The above commented out code will create a copy of list, so the items in output will not affect the original ones.
list.forEach(function(item) {
// new one overwrites old one.
keyStore[item.place] = item;
});
var key;
for (key in keyStore) {
output.push(keyStore[key]);
}
return output;
};
console.log(removeDuplicate(list));
3 way to remove duplicate objects from array
let list = [{place:"AAA",name:"Me"},
{place:"BBB",name:"You"},
{place:"AAA",name:"Him"}];
let output1 = Array.from(new Set(list.map(list=>list.place))).map(place=>{
return {
place: place,
name: list.find(a=>a.place===place).name
}
})
console.log('------------------------1st way')
console.log(output1)
let output2 = list.reduce((accumulator, element) => {
if (!accumulator.find(el => el['place'] === element['place'])) {
accumulator.push(element);
}
return accumulator;
},[]);
console.log('------------------------2nd way')
console.log(output2)
const output3 = [];
const map = new Map();
for (const object of list) {
if(!map.has(object.place)){
map.set(object.place, true);
output3.push({
place: object.place,
name: object.name
});
}
}
console.log('------------------------3rd way')
console.log(output3)

Categories