Javascript loop through array of strings and ints - javascript

Having this array:
const xx = [
{
name: "Alex",
income: 324300,
total: 3030000
},
{
name: "Snake",
income: 3433000,
total: 34323000
},
{
name: "Wake",
income: 4,
total: 3
}
];
I want to loop through it and do something if the value is an int (income and total). How do i go about doing it?
This is what i have tried so far, i dont really know how to take out the objects value and test if it is an int
for (var key in xx) {
var arr = xx[key];
for( var i = 0; i < arr.length; i++ ) {
var obj = arr[ i ];
}
}
}

try:
const xx = [
{
name: "Alex",
income: 324300,
total: 3030000
},
{
name: "Snake",
income: 3433000,
total: 34323000
},
{
name: "Wake",
income: 4,
total: 3
}
];
xx.forEach(item => {
Object.keys(item).forEach(key => {
if (!isNaN(parseInt(item[key])) && isFinite(item[key])) {
// do something here
console.log('INT: ' + item[key]);
}
});
});

You need to exchange internal for with the external. and use:
typeof xx[i][k] === "number" OR xx[i][k] === +xx[i][k] to check if value is
a number.
parseInt(xx[i][k]) === xx[i][k] to check if value is an integer
number.
See example:
const xx = [{
name: "Alex",
income: 324300,
total: 3030000
}, {
name: "Snake",
income: 34.33000,
total: 34323000
}, {
name: "Wake",
income: 4,
total: 3
}];
for (var i = 0; i < xx.length; i++) {
for (var k in xx[i]) {
//if(parseInt(xx[i][k]) === xx[i][k]) //integer
//if(typeof xx[i][k] == "number") //number
if (xx[i][k] === +xx[i][k]) { //number
console.log(k + ": " + xx[i][k]);
}
}
}

Related

remove the second occurrence of array object with same name

I have this array (java script array of objects)
users=[{name:'arrow',age:50,id:444}
{name:'bow',age:66,id:884}
{name:'arrow',age:30,id:99},
{name:'apple',age:50,id:999}
{name:'bow',age:50,id:9669}]
I want to remove second occurrence of same name , in this case , I want to remove {name:'arrow',age:30,id:99} and {name:'bow',age:50,id:9669} and retain first occurrences{name:'arrow',age:50,id:444} and {name:'bow',age:66,id:884}
Resulting array should be :
users= [{name:'arrow',age:50,id:444}
{name:'bow',age:66,id:884},
{name:'apple',age:50,id:999}]
const users = [
{ name: 'arrow', age: 50, id: 444 },
{ name: 'bow', age: 66, id: 884 },
{ name: 'arrow', age: 30, id: 99 },
{ name: 'apple', age: 50, id: 999 },
{ name: 'bow', age: 50, id: 9669 }
]
const uniqueUsers = users.reduce((acc, user) => {
if (!acc.find(u => u.name === user.name)) {
acc.push(user)
}
return acc
}, [])
I'd go with the approach of array.filter:
function removeDuplicateKeyFromArray(arrayOfObjects,keyName){
keyHolder = {}
arrayOfObjects.filter((obj)=>{
if(keyHolder[obj.keyName]){
return false
}
keyHolder[obj.keyName] = 1 //or true
return true
})
}
I would create 2 for-loops, to filter out any duplicates.
here's my code:
let users = [{name:'arrow',age:50,id:444},
{name:'bow',age:66,id:884},
{name:'arrow',age:30,id:99},
{name:'apple',age: 50,id: 990},
{name:'bow',age: 50,id: 9669}]
for (let i = 0; i < users.length; i++) {
for(let x = 0; i < users.length; i++) {
if(users[i].name == users[x].name) {
users.splice(users[x], 1)
}
}
}

Update the value of nested object in the array based on the key

i have two array of objects like below, am trying to compare two arrays and looking to update the object total value of arr1 if the id matches with arr2.
const arr1 = [
{
id: 1,
value: { total: 0 },
},
{
id: 2,
value: { total: 0 },
},
{
id: 3,
value: { total: 0 },
},
id: 4,
value: { total: 0 },
},
];
const arr2 = [
{
id: 2,
value: 3 ,
},
{
id: 3,
value: 5,
},
];
I am trying to compare two arrays and looking to update the object total value of arr1 if the id matches with arr2
expected result is
const arr1 = [
{
id: 1,
value: { total: 0 },
},
{
id: 2,
value: { total: 3 },
},
{
id: 3,
value: { total: 5 },
},
{
id: 4,
value: { total: 0 },
},
];
I have tried the below code,
arr1.map((item) => {
arr2.find((element) => {
if (element.id === item.id ) {
item = {
...item,
value: {
...item.value,
total: item.value.total + element.value,
},
};
console.log(item);
}
});
return item;
});
I have changed the find function to the filter function and will add the result to the original array.
try this
const arr1 = [
{
id: 1,
value: { total: 0 },
},
{
id: 2,
value: { total: 0 },
},
{
id: 3,
value: { total: 0 },
},
{
id: 4,
value: { total: 0 },
}
]
const arr2 = [
{
id: 2,
value: 3 ,
},
{
id: 3,
value: 5,
},
];
arr1.map((item) => {
let result = arr2.filter((element) => element.id == item.id)
if(result && result.length) {
item.value.total += result[0].value
}
return item;
});
console.log(arr1)
You have to assign map to your array:
this.arr1 = this.arr1.map((item) => {
this.arr2.find((element) => {
if (element.id === item.id) {
item = {
...item,
value: {
...item.value,
total: item.value.total + element.value,
},
};
console.log(item);
}
});
return item;
});
If each object's id is unique (within each array), you can do:
arr1.forEach((obj1) => {
const obj2Match = arr2.find((obj2) => obj1.id === obj2.id );
if (obj2Match) {
obj1.value.total += obj2Match.value;
}
});
If more than one object can have the same id (e.g. arr2 has two objects that have the id of 2), then you can do:
arr1.forEach((obj1) => {
const obj2Matches = arr2.filter((obj2) => obj1.id === obj2.id );
if (obj2Matches.length) {
obj1.value.total += obj2Matches.reduce(((accum, curr) => accum + curr.value), 0);
}
});
Complexity:
Time: O(N * M)
Space: O(M)
N => arr1.length, M => arr2.length
You could do something like this:
arr2.map((x) => {
let result = arr1.filter((a1) => a1.id === x.id);
if (result.length > 0) {
x.total = result[0].total;
}
return x;
});

How do you get rid of double quotes from "name" and "count" from the console output in JavaScript?

I have trouble turning the input:
["apple", "banana", "carrot", "durian", "eggplant", "apple", "carrot"]
into the right output:
[{ name: "Apple", count: 2 }, { name: "Banana", count: 1 }, { name: "Carrot", count: 2 }, { name: "Durian", count: 1 }, { name: "Eggplant", count: 1 }],
where I have trouble with the wrong output:
[{"name":"Apple","count":2},{"name":"Banana","count":1},{"name":"Carrot","count":2},{"name":"Durian","count":1},{"name":"Eggplant","count":1}].
How can I have the right output:
[{ name: "Apple", count: 2 }, { name: "Banana", count: 1 }, { name: "Carrot", count: 2 }, { name: "Durian", count: 1 }, { name: "Eggplant", count: 1 }]
with the use of console.log() method?
<html>
<body>
<script>
var input = ["apple", "banana", "carrot", "durian", "eggplant", "apple", "carrot"];
var A = 0;//to count the number of apples
var B = 0;//to count the number of bananas
var C = 0;//to count the number of carrots
var D = 0;//to count the number of durians
var E = 0; //to count the number of eggplants
for (var i = 0; i < input.length; i++)
{
if (input[i] == "apple")
{
A += 1;
}
if (input[i] == "banana")
{
B += 1;
}
if (input[i] == "carrot")
{
C += 1;
}
if (input[i] == "durian")
{
D += 1;
}
if (input[i] == "eggplant")
{
E += 1;
}
}
let x1 = { name: 'Apple',
count: A };
let x2 = { name: 'Banana',
count: B };
let x3 = { name: 'Carrot',
count: C };
let x4 = { name: 'Durian',
count: D };
let x5 = { name: 'Eggplant',
count: E };
var output = [];
output.push(x1);
output.push(x2);
output.push(x3);
output.push(x4);
output.push(x5);
console.log("output = ", output);
document.getElementById('output').innerHTML = JSON.stringify(output);
</script>
</body>
</html>
You can use regular expression like below:
var yourStringifiedResult = "[{\"name\":\"Apple\",\"count\":2},{\"name\":\"Banana\",\"count\":1},{\"name\":\"Carrot\",\"count\":2},{\"name\":\"Durian\",\"count\":1},{\"name\":\"Eggplant\",\"count\":1}]";
yourStringifiedResult = yourStringifiedResult.replace(/"(\w+)"\s*:/g, '$1:');
console.log(yourStringifiedResult);
Working sample:
var yourStringifiedResult = "[{\"name\":\"Apple\",\"count\":2},{\"name\":\"Banana\",\"count\":1},{\"name\":\"Carrot\",\"count\":2},{\"name\":\"Durian\",\"count\":1},{\"name\":\"Eggplant\",\"count\":1}]";
yourStringifiedResult = yourStringifiedResult.replace(/"(\w+)"\s*:/g, '$1:');
console.log(yourStringifiedResult);
Just add this line after push the all objects in array:
let outputInString = "";
for (let fruit of input) outputInString += "Name: " + fruit.name + ", Count: " + fruit.count + ", ";
document.getElementById('output').innerHTML = outputInString;

combine array of objects by key

I am trying to combine/merge 2 array of objects by key in my case id.
Objective:
I am expecting a results where I would have array containing all objects with ids 1,2,3,4 as per example
Order of merging should not affect number of objects in result for example combine(arr1,arr2) or combine(arr2,arr1) should have array with same number of objects
Order of merging can only affect resulting object for example in case of combine(arr1,arr2) arr2 key,values pair can override arr1 key,values just like deep jquery extend $.extend( true, arr1ObJ,arr2ObJ );
JSFIDDLE: https://jsfiddle.net/bababalcksheep/u2c05nyj/
Sample Data:
var arr1 = [{
id: 1,
name: "fred",
title: "boss"
}, {
id: 2,
name: "jim",
title: "nobody"
}, {
id: 3,
name: "bob",
title: "dancer"
}];
var arr2 = [{
id: 1,
wage: "300",
rate: "day"
}, {
id: 2,
wage: "10",
rate: "hour"
}, {
id: 4,
wage: "500",
rate: "week"
}];
var Result = [{
"id": 1,
"name": "fred",
"title": "boss",
"wage": "300",
"rate": "day"
}, {
"id": 2,
"name": "jim",
"title": "nobody",
"wage": "10",
"rate": "hour"
}, {
id: 3,
name: "bob",
title: "dancer"
}, {
id: 4,
wage: "500",
rate: "week"
}];
Here's a solution. It basically goes through each element of arr2 and checks to see if there's an element with a matching ID arr1. If so, it updates the matching element in arr1 with arr2's values. If there is no match, it simply pushes the element in arr2 onto arr1.
var arr1 = [{id: 1,name: 'fred',title: 'boss'},
{id: 2,name: 'jim',title: 'nobody'},
{id: 3,name: 'bob',title: 'dancer'}];
var arr2 = [{id: 1,wage: '300',rate: 'day'},
{id: 2,wage: '10',rate:'hour'},
{id: 4,wage: '500',rate: 'week'}];
function combineArrays(arr1, arr2) {
for(var i = 0; i < arr2.length; i++) {
// check if current object exists in arr1
var idIndex = hasID(arr2[i]['id'], arr1);
if(idIndex >= 0){
//update
for(var key in arr2[i]){
arr1[idIndex][key] = arr2[i][key];
}
} else {
//insert
arr1.push(arr2[i]);
}
}
return arr1;
}
//Returns position in array that ID exists
function hasID(id, arr) {
for(var i = 0; i < arr.length; i ++) {
if(arr[i]['id'] === id)
{
return i;
}
}
return -1;
}
var combine = combineArrays(arr1, arr2);
output(combine);
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
var arr1 = [{
id: 1,
name: 'fred',
title: 'boss'
}, {
id: 2,
name: 'jim',
title: 'nobody'
}, {
id: 3,
name: 'bob',
title: 'dancer'
}];
var arr2 = [{
id: 1,
wage: '300',
rate: 'day'
}, {
id: 2,
wage: '10',
rate: 'hour'
}, {
id: 4,
wage: '500',
rate: 'week'
}];
function combineArrays(arr1, arr2) {
for (var i = 0; i < arr2.length; i++) {
var idIndex = hasID(arr2[i]['id'], arr1);
if (idIndex >= 0) {
for (var key in arr2[i]) {
arr1[idIndex][key] = arr2[i][key];
}
} else {
arr1.push(arr2[i]);
}
}
return arr1;
}
function hasID(id, arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i]['id'] === id) {
return i;
}
}
return -1;
}
var combine = combineArrays(arr1, arr2);
output(combine);
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
How about something along the lines of this:
function combineArrays(arr1, arr2, keyFunc) {
var combined = [],
keys1 = arr1.map(keyFunc),
keys2 = arr2.map(keyFunc),
pos1 = keys1.map(function (id) {
return keys2.indexOf(id);
}),
pos2 = keys2.map(function (id) {
return keys1.indexOf(id);
});
arr1.forEach(function (item, i) {
combined.push( $.extend(item, arr2[pos1[i]]) );
});
arr2.forEach(function (item, i) {
if (pos2[i] === -1) combined.push( item );
});
return combined;
}
used as
var combine = combineArrays(arr1, arr2, function (item) {
return item.id;
});
var arr1 = [
{ id: 1, name: 'fred', title: 'boss' },
{ id: 2, name: 'jim', title: 'nobody' },
{ id: 3, name: 'bob', title: 'dancer' }
];
var arr2 = [
{ id: 1, wage: '300', rate: 'day' },
{ id: 2, wage: '10', rate: 'hour' },
{ id: 4, wage: '500', rate: 'week' }
];
function combineArrays(arr1, arr2, keyFunc) {
var combined = [],
keys1 = arr1.map(keyFunc),
keys2 = arr2.map(keyFunc),
pos1 = keys1.map(function (id) {
return keys2.indexOf(id);
}),
pos2 = keys2.map(function (id) {
return keys1.indexOf(id);
});
arr1.forEach(function (item, i) {
combined.push( $.extend(item, arr2[pos1[i]]) );
});
arr2.forEach(function (item, i) {
if (pos2[i] === -1) combined.push( item );
});
return combined;
}
var combine = combineArrays(arr1, arr2, function (item) {
return item.id;
});
output(combine);
//
//
//
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Better way to join two arrays of objects on two properties?

I'm trying to combine two arrays of objects, based on two properties, and rewrite the names of other properties in the joined dataset.
This is what the datasets look like:
var xData = [
{ row_id: 1, date: '2013-04-01', cost: 18 },
{ row_id: 2, date: '2013-04-01', cost: 27 } ...
];
var yData = [
{ row_id: 1, date: '2013-04-01', cost: 48 },
{ row_id: 3, date: '2013-04-01', cost: 37 } ...
];
The properties I want to join on are the row_id and date properties, and I want to rewrite cost to x_cost and y_cost respectively. I also want to deal with missing values. So this is what I want to end up with:
var combinedData = [
{ row_id: 1, date: '2013-04-01', x_cost: 18, y_cost: 48 },
{ row_id: 2, date: '2013-04-01', x_cost: 27, y_cost: null },
{ row_id: 3, date: '2013-04-01', x_cost: null, y_cost: 37 } ...
];
This is my code right now. It's pretty horrible:
combineXAndYDatasets: function(xData, yData) {
// Index both datasets by ID and date.
var x_indexed_by_id_and_date = {};
xData.forEach(function(d) {
var k = d.row_id + '_' + d.date;
x_indexed_by_id_and_date[k] = d;
});
var y_indexed_by_id_and_date = {};
yData.forEach(function(d) {
var k = d.row_id + '_' + d.date;
y_indexed_by_id_and_date[k] = d;
});
var combinedData = [];
// Iterate over ydata, join with xdata if possible.
for (var row_id in y_indexed_by_id_and_date) {
var row = JSON.parse(JSON.stringify(y_indexed_by_id_and_date[row_id]));
row.y_cost = +y_indexed_by_id_and_date[row_id].cost;
if (row_id in x_indexed_by_id_and_date) {
row.x_cost = +x_indexed_by_id_and_date[row_id].cost;
} else {
row.x_cost = null;
}
combinedData.push(row);
}
// Iterate over xdata, add anything that wasn't in ydata.
for (var x_row_id in x_indexed_by_id_and_date) {
if (!(x_row_id in y_indexed_by_id_and_date)) {
var x_row = JSON.parse(JSON.stringify(x_indexed_by_id_and_date[x_row_id]));
x_row.y = null;
x_row.x = +x_row.cost;
combinedData.push(x_row);
}
}
return combinedData;
}
What can I do to make this less awful?
I'm using jQuery, and I could add e.g. Underscore if that would help.
You could take advantage of reduce to reduce each array to a dictionary and then convert that dictionary back into an array. Something like this (vanilla JS, not IE 8 compatible out-of-the-box):
var xData = [
{ row_id: 1, date: '2013-04-01', cost: 18 },
{ row_id: 2, date: '2013-04-01', cost: 27 }
];
var yData = [
{ row_id: 1, date: '2013-04-01', cost: 48 },
{ row_id: 3, date: '2013-04-01', cost: 37 }
];
var xDataDict = xData.reduce(function(p,c) {
createDictionaryEntry(p,c,c.cost,null)
return p;
},{});
xAndYDataDict = yData.reduce(function(p,c) {
createDictionaryEntry(p,c,null,c.cost)
return p;
}, xDataDict);
var combinedData = Object.keys(xAndYDataDict).map(function(key) {
return xAndYDataDict[key];
});
alert(JSON.stringify(combinedData));
function createDictionaryEntry(p,c,x_cost,y_cost) {
var key = c.row_id + "-" + c.date;
if (p[key]) {
p[key].x_cost = p[key].x_cost || x_cost;
p[key].y_cost = p[key].y_cost || y_cost;
} else {
p[key] = {
row_id: c.row_id,
date: c.date,
x_cost: x_cost,
y_cost: y_cost
}
}
}
Note that combinedData won't be in any guaranteed order, so if that's important, you can always sort it afterwards.
Using underscore:
var xData = [
{ row_id: 1, date: '2013-04-01', cost: 18 },
{ row_id: 2, date: '2013-04-01', cost: 27 }
];
var yData = [
{ row_id: 1, date: '2013-04-01', cost: 48 },
{ row_id: 3, date: '2013-04-01', cost: 37 }
];
var xDataDict = _.reduce(xData, function(p,c) {
createDictionaryEntry(p,c,c.cost,null)
return p;
},{});
xAndYDataDict = _.reduce(yData,function(p,c) {
createDictionaryEntry(p,c,null,c.cost)
return p;
}, xDataDict);
var combinedData = _.map(Object.keys(xAndYDataDict),function(key) {
return xAndYDataDict[key];
});
alert(JSON.stringify(combinedData));
function createDictionaryEntry(p,c,x_cost,y_cost) {
var key = c.row_id + "-" + c.date;
if (p[key]) {
p[key].x_cost = p[key].x_cost || x_cost;
p[key].y_cost = p[key].y_cost || y_cost;
} else {
p[key] = {
row_id: c.row_id,
date: c.date,
x_cost: x_cost,
y_cost: y_cost
}
}
}
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Categories

Resources