Convert foreach into map function in javascript - javascript

This is my function in foreach loop for creating object which has property and value as word and its count, but i want to convert it in map according to es6
function harmlessRamsonNote(noteText,magazineText)
{
var noteArr = noteText.split(' ');
var magazineArr = magazineText.split(' ');
var magazineObj = {};
magazineArr.forEach(word => {
if(!magazineObj[word])
{
magazineObj[word] = 0;
}
magazineObj[word]++;
});
console.log(magazineObj);
};

magazineArr.map((word, index, array) => {
!magazineObj[word] ? magazineObj[word] = 0 : magazineObj[word]++;
})

map will return an new item for each item. Instead you can use reduce.
const magazineObj = magazineArr.reduce((acc,word) => {
acc[word] = (acc[word] || -1) + 1;
}, {});

Related

get 2 array unique and duplicate elements from parent array

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]));

Function will log value but return undefined

The function below will log the value of newData but returns undefined when called. Does anyone know why this might be? Also, any feedback on the function itself would be greatly appreciated!
export const filterByDateTimeRange = (data=[{}], timeKey=[], startTime=moment(), stopTime=moment()) => {
let newData = [];
let i = 0;
for(const item of data) {
let time;
let index = 0
timeKey.map(key => {
time ? time = time[key] : time = item[key];
index++
if(index === timeKey.length) {
if(moment(time).isBetween(startTime, stopTime, undefined, '[)')) {
newData.push(item)
};
i++;
if(i === data.length) {
console.log(newData);
return (newData);
}
}
})
}
}
The map function is usually used to transform a collection and store the results, for example:
var squares = [2, 3, 4].map(x => { return x * x });
// result is squares = [4, 9, 16]
The forEach function is more appropriate to use here since you just want to loop over the array and don't care about storing a transformation.
Then when the outer loop finishes your function can return newData
export const filterByDateTimeRange = (data=[{}], timeKey=[], startTime=moment(), stopTime=moment()) => {
let newData = [];
let i = 0;
for(const item of data) {
let time;
let index = 0
timeKey.forEach(key => { //changed to a forEach loop
time ? time = time[key] : time = item[key];
index++
if(index === timeKey.length) {
if(moment(time).isBetween(startTime, stopTime, undefined, '[)')) {
newData.push(item)
};
i++;
if(i === data.length) {
console.log(newData);
}
}
});
}
return newData; //add the return after your loop finishes
}
This return inside a map function. Not return of filterByDateTimeRange(). If you want to return newData. Replace map function by for loop.
Map: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

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 to make the grouping fastest, provided that the data in the array also show the object nodeJs

Hello this is my array;
arr =[{cNo:1,buyOrSel:'A',ip:192.168.1.1},{cNo:1,buyOrSel:'S',ip:192.168.1.1},{cNo:2,buyOrSel:'S',ip:192.168.1.2},{cNo:3,buyOrSel:'A',ip:192.168.1.1},{cNo:4,buyOrSel:'S',ip:192.168.1.3},{cNo:5,buyOrSel:'S',ip:192.168.1.2}]
I want to group in Object like this;
[{cNo:'1,3',ip:192.168.1.1},{cNo:'2,5',ip:192.168.1.2}]
I don't want to use nested For loop.What is the best way for this ?
let arr = [{cNo:1,buyOrSel:'A',ip:"192.168.1.1"},{cNo:1,buyOrSel:'S',ip:"192.168.1.1"},{cNo:2,buyOrSel:'S',ip:"192.168.1.2"},{cNo:3,buyOrSel:'A',ip:"192.168.1.1"},{cNo:4,buyOrSel:'S',ip:"192.168.1.3"},{cNo:5,buyOrSel:'S',ip:"192.168.1.2"}];
arr = arr.reduce((prev, a) => {
let cNo = prev[a.ip] = prev[a.ip] || [];
if (cNo.indexOf(a.cNo) < 0) {
prev[a.ip].push(a.cNo);
};
return prev
}, {});
arr = Object.keys(arr).map(key => {
return {
cNo: arr[key].join(),
ip: key
}
});
console.log(arr);
you can use object for better grouping.
and instead of pushing only cNo, you can push whole object too.
let arr = [{cNo:1,buyOrSel:'A',ip:"192.168.1.1"},{cNo:1,buyOrSel:'S',ip:"192.168.1.1"},{cNo:2,buyOrSel:'S',ip:"192.168.1.2"},{cNo:3,buyOrSel:'A',ip:"192.168.1.1"},{cNo:4,buyOrSel:'S',ip:"192.168.1.3"},{cNo:5,buyOrSel:'S',ip:"192.168.1.2"}];
let objectByIP = {};
arr.forEach(element => {
if (!objectByIP[element.ip]) {
objectByIP[element.ip] = [element.cNo];
} else {
objectByIP[element.ip].push(element.cNo);
}
});
console.log(objectByIP);
console.log(Object.keys(objectByIP));
you can use map():
let a = arr.map(a=>{ return {cNo: a.cNo, ip: a.ip}})

JQuery remove duplicate from array where string contains same text

I have an array with X number of items. Each has variables separated by a pipe character. In a loop I can split on the pipe to get the second item; but how do I splice to remove the duplicate.
"Sometext|22621086|address|333629dc87894a7ea7df5291fa6d1836|PC_E|1803"
"Sometext2|22622138|working|d3e70175ffe942568cd21f1cf96f4d63|PC_E|1803"
"Sometext3|22622138|working|851946e6325445da99c113951590f714|PC_E|1803"
Results should be this.
"Sometext|22621086|address|333629dc87894a7ea7df5291fa6d1836|PC_E|1803"
"Sometext2|22622138|working|d3e70175ffe942568cd21f1cf96f4d63|PC_E|1803"
Note that the duplicate 22622138 is a random number so the solution needs to work for any number in this location (it's always in the arr[1] position).
This is what I tried:
$.each(arr_transcript, function (i, e) {
if (e.length != 0) {
var arr = e.split("|")
var i = arr_transcript.indexOf(arr[1]);
if (i != -1) {
arr_transcript.splice(i, 1);
}
}
});
Here's a generic function:
function uniqBy(a, key) {
let seen = new Set();
return a.filter(item => {
let k = key(item);
return !seen.has(k) && seen.add(k);
});
};
var data = [
"Sometext|22621086|address|333629dc87894a7ea7df5291fa6d1836|PC_E|1803",
"Sometext2|22622138|working|d3e70175ffe942568cd21f1cf96f4d63|PC_E|1803",
"Sometext3|22622138|working|851946e6325445da99c113951590f714|PC_E|1803"
];
var result = uniqBy(data, item => item.split('|')[1]);
console.log(result)
See here for more info.
Create a map of the numbers you want to check against, and then filter based on that
var arr_transcript = [
"Sometext|22621086|address|333629dc87894a7ea7df5291fa6d1836|PC_E|1803",
"Sometext2|22622138|working|d3e70175ffe942568cd21f1cf96f4d63|PC_E|1803",
"Sometext3|22622138|working|851946e6325445da99c113951590f714|PC_E|1803"
];
var map = arr_transcript.map(function(text) {
return text.split('|')[1];
});
var filtered = arr_transcript.filter(function(item, index) {
return index === map.lastIndexOf( map[index] );
});
console.log(filtered)

Categories