i have to make a object from array then i can work with it letter.
i am trying this code it work's but output getting only last one
let datas = "team1 1, team2 2, team3 3";
let teamdata = datas.split(" ");
var myObj = (function () {
var result = { Tname: null, count: null };
datas.split(/\s*\,\s*/).forEach(function (el) {
var parts = el.split(/\s* \s*/);
result.Tname = parts[0];
result.count = parseInt(parts[1]);
});
return result;
})();
console.log(myObj);
output getting { Tname: 'team3', count: 3 }
need output
[{name: "team1", count: 1},
{name: "team2", count: 2},
{name: "team3", count: 3}]
Simply, You could do it with
String.split() and Array.map()
let datas = "team1 1, team2 2, team3 3";
let teamdata = datas.split(", "); // ['team1 1', 'team2 2', 'team3 3']
let result = teamdata.map(team=>({team:team.split(/\s+/)[0],count:+team.split(/\s+/)[1]}))
console.log(result);
expected output:
[{name: "team1", count: 1},
{name: "team2", count: 2},
{name: "team3", count: 3}]
i have to make a object
But you then claim that your expected output is an array, not an object:
[
{name: "team1", count: 1},
{name: "team2", count: 2},
{name: "team3", count: 3}
]
In that case, make an array and then .push() to that array within the loop:
var result = [];
datas.split(/\s*\,\s*/).forEach(function (el) {
var parts = el.split(/\s* \s*/);
result.push({
Tname: parts[0],
count: parseInt(parts[1])
});
});
return result;
This should work fine:
let datas = "team1 1, team2 2, team3 3";
var results = [];
var myObj = (function () {
var result = { Tname: null, count: null };
datas.split(/\s*\,\s*/).forEach(function (el) {
var parts = el.split(/\s* \s*/);
result.Tname = parts[0];
result.count = parseInt(parts[1]);
results.push(result);
});
return results;
})();
console.log(results)
The problem with your code was that you successfully splitted the string and converted it to the object but as you are expecting the result to be in the array you were not storing the object rather were rewriting the same object time and again.
Related
Is there a way to update a property in object array based on the number of times some other property is present as element in some other array
I have 2 arrays, array1 and array2:
var array1 = ["JOHN", "JACK", "JACK"];
var array2 = [
{count: 9, value: "JACK"},
{count: 9, value: "JOHN"},
{count: 2, value: "TEST"}
];
Expected output :
[
{count: 7, value: "JACK"}, // count = 9 - 2
{count: 8, value: "JOHN"}, // count = 9 - 1
{count: 2, value: "TEST"}
]
In array1, "JACK" is present twice, so I need to reduce count by 2, similarly "JOHN" is present once and hence its reduced by 1, "TEST" is not present so unchanged.
I tried the following
array1.map(item => {
return array2.find( p => p["value"] === item);
});
With this, I am getting the below output,
[
{count: 9, value: "JOHN"},
{count: 9, value: "JACK"},
{count: 9, value: "JACK"}
]
I am not sure whether it can be achieved using single lambda expression.
Thanks in advance!
You can get the result using array .map() and .filter() methods, assuming you are not allowed to change the original array:
var array1 = ["JOHN", "JACK", "JACK"];
var array2 = [{count: 9, value: "JACK"}, {count: 9, value: "JOHN"}, {count: 2, value: "TEST"}]
var result = array2.map(({value, count}) => ({value, count: count - array1.filter(a=>a===value).length}))
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using .filter() check how many time a value is present in array1
Then subtract that result from current array2 count.
Then just return a new array of objects with the updated count.
You can use reduce and map
Loop over array1 and create a mapper object with names as key and repetition of names as value
Loop over array2 and see if the name is present in mapper subtract respective value from
const array1 = ["JOHN", "JACK", "JACK"];
const array2 = [{count: 9, value: "JACK"},{count: 9, value: "JOHN"},{count: 2, value: "TEST"}]
const mapper = array1.reduce((op, inp) => {
op[inp] = op[inp] || 0;
op[inp]++;
return op;
}, Object.create(null))
let final = array2.map(({count,value}) =>({
value,
count: count - (mapper[value] || 0)
}))
console.log(final)
Assuming you are allowed to change the original array. ALSO assuming we are not talking 10s of thousand entries since I look up the value in the name array each time:
var array1 = ["JOHN", "JACK", "JACK"];
var array2 = [{count: 9, value: "JACK"},
{count: 9, value: "JOHN"},
{count: 2, value: "TEST"}]
array2.forEach(item => item.count -= array1.filter(val => val === item.value).length);
console.log(array2);
Less resources:
var array1 = ["JOHN", "JACK", "JACK"];
var array2 = [{count: 9, value: "JACK"},
{count: 9, value: "JOHN"},
{count: 2, value: "TEST"}]
// create lookup table
const names = array1.reduce((arr,cur) => { arr[cur] = (arr[cur]||0) + 1; return arr;},{})
// subtract if present
array2.forEach(item => item.count -= (names[item.value] || 0));
console.log(array2);
I am new to JavaScript and while learning it trying to filter an employee based on education but my filter is returning a null value. Can anyone help me understand why is this so?
var employeeEdu = [{education: 'Masters'}];
var employees = [{id: 1, age: 35, name: 'James', dept: 'IT', education: 'Masters'},
{id: 2, age: 25, name: 'David', dept: 'Accounts', education: 'High School'},
{id: 3, age: 45,name: 'Tim', dept: 'HR', education: 'Graduate'},
{id: 4, age: 50,name: 'Vinod', dept: 'IT', education: 'PHD'}];
function chooseQualified(arrEmployee, empEducation) {
return arrEmployee.filter(function(emp) {
return emp.education === empEducation.education;
// return emp.education === 'Masters';
});
}
console.log(chooseQualified(employees, employeeEdu));
It's because employeeEdu is an array, and employeeEdu.education is undefined. What you need to do is to checkout employeeEdu[0].education:
var employeeEdu = [{education: 'Masters'}];
var employees = [{"id":1,"age":35,"name":"James","dept":"IT","education":"Masters"},{"id":2,"age":25,"name":"David","dept":"Accounts","education":"High School"},{"id":3,"age":45,"name":"Tim","dept":"HR","education":"Graduate"},{"id":4,"age":50,"name":"Vinod","dept":"IT","education":"PHD"}];
function chooseQualified(arrEmployee, empEducation) {
return arrEmployee.filter(function(emp) {
return emp.education === empEducation[0].education;
// return emp.education === 'Masters';
});
}
console.log(chooseQualified(employees, employeeEdu));
Another solution is to remove the wrapping array:
employeeEdu = {education: 'Masters'};
Like #Ori Drori says, employeeEdu is an array, so empEducation.education is undefined, but empEducation[0].education is 'Masters'. I suggest that employeeEdu be a object instead of array, like below code. var employeeEdu = {education: 'Masters'};
var employeeEdu = {education: 'Masters'};
var employees = [{id: 1, age: 35, name: 'James', dept: 'IT', education: 'Masters'},
{id: 2, age: 25, name: 'David', dept: 'Accounts', education: 'High School'},
{id: 3, age: 45,name: 'Tim', dept: 'HR', education: 'Graduate'},
{id: 4, age: 50,name: 'Vinod', dept: 'IT', education: 'PHD'}];
function chooseQualified(arrEmployee, empEducation) {
return arrEmployee.filter(function(emp) {
return emp.education === empEducation.education;
// return emp.education === 'Masters';
});
}
console.log(chooseQualified(employees, employeeEdu));
/* #Params:
* array0 [Array of Objects]: Array to search through.
* array1 [Array of Objects]: Array with the key/value to search for.
* key [String]: Key of the object in array1.
* index [Number](optional): Index of array1. default: 0.
*/
// Returns a new array of objects witch matched by key/value from the two given arrays.
function findByKV(array0, array1, key, index = 0) {
// Get the value of the key to be searched for
var value = array1[index][key];
// Filter the array to be searched obj is each Object in array1
filter()
array0.filter(function(obj) {
// Get each obj key of array0 and ...
Object.keys() .some()
return Object.keys(obj).some(function(key) {
// ...return true if at least one String value matches the value of the key in array1
.toString() .indexOf()
return obj[key].toString().indexOf(value) != -1;
var target0 = [{education: 'Masters'}];
var target1 = [{dept: 'IT',education: ''}];
var employees = [
{id: 1,age: 35,name: 'James',dept: 'IT',education: 'Masters'},
{id: 2,age: 25,name: 'David',dept: 'Accounts',education: 'High School'},
{id: 3,age: 45,name: 'Tim',dept: 'HR',education: 'Graduate'},
{id: 4,age: 50,name: 'Vinod',dept: 'IT',education: 'PHD'},
{id: 5,age: 46,name: 'Matt',dept: 'IT',education: 'Masters'}
];
function findByKV(array0, array1, key, index = 0) {
var value = array1[index][key];
var array2 = array0.filter(function(obj) {
return Object.keys(obj).some(function(key) {
return obj[key].toString().indexOf(value) != -1;
});
});
return array2;
}
var result0 = findByKV(employees, target0, 'education');
var result1 = findByKV(employees, target1, 'dept');
console.log('Found targrt0: ' + JSON.stringify(result0, null, 2));
console.log('Found target1: ' + JSON.stringify(result1, null, 2));
So, I have something like this:
objArray1 = [ { candidate1: "Alex" , votes: 4}, { candidate2: "Paul", votes: 3}];
objArray2 = [ { candidate1: "Alex" , votes: 7}, { candidate2: "Ben", votes: 3}, { candidate3: "Melisa", votes:8 }];
I am trying to use javascript to make an array with all the candidates and see how many votes each of them have. The part to calculate the votes is easy, but I don't know how to put all the candidates in one array.
I should get an array with: Alex, Paul, Ben and Melisa.
Thank you!
You could use a hashtable and group by name.
var array1 = [ { candidate1: "Alex" , votes: 4}, { candidate2: "Paul", votes: 3}],
array2 = [ { candidate1: "Alex" , votes: 7}, { candidate2: "Ben", votes: 3}, { candidate3: "Melisa", votes:8 }],
grouped = [array1, array2].reduce(function (hash) {
return function (r, a) {
a.forEach(function (o, i) {
var name = o['candidate' + (i + 1)];
if (!hash[name]) {
hash[name] = { candidate: name, votes: 0 };
r.push(hash[name]);
}
hash[name].votes += o.votes;
});
return r;
};
}(Object.create(null)), []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var candidates = [];
var found = 0;
for(var i=0;objArray1.length>i;i++){
found = 0;
//add votes to candidate array
for(var j=0;candidates.length>j;j++){
if(candidates[j].name==objArray1[i][Object.keys(objArray1[i])[0]]){
candidates[j].votes = candidates[j].votes+objArray1[i].votes;
found = 1;
}
}
//if condidate not found in votes array, create new
if(found==0){
var tmp = {};
tmp.name = objArray1[i].candidate;
tmp.votes = objArray1[i].votes;
//add to array
candidates.push(tmp);
}
}
console.log(candidates);
Generate an object which holds property name as name and vote count as value.
var objArray1 = [ { candidate1: "Alex" , votes: 4}, { candidate2: "Paul", votes: 3}], objArray2 = [ { candidate1: "Alex" , votes: 7}, { candidate2: "Ben", votes: 3}, { candidate3: "Melisa", votes:8 }];
var res = []
// cobine two arrays
.concat(objArray1, objArray2)
// iterate over the arrays
.reduce(function(obj, o) {
// get the key except the votes
var key = Object.keys(o).find(function(k) {
return k != 'votes';
})
// define property if not already defined
obj[key] = obj[key] || 0;
// add the vote count
obj[key] += o.votes;
// return object refernece
return obj;
// set initial value as empty object
}, {});
console.log(res);
// get the names array if need
console.log(Object.keys(res));
Short solution using Array.prototype.concat(), Array.prototype.reduce() and Array.prototype.map() functions:
var objArray1 = [ { candidate1: "Alex" , votes: 4}, { candidate2: "Paul", votes: 3}],
objArray2 = [ { candidate1: "Alex" , votes: 7}, { candidate2: "Ben", votes: 3}, { candidate3: "Melisa", votes:8 }],
grouped = objArray1.concat(objArray2).reduce(function(r, o){
var k = Object.keys(o).filter(function(k){
return k.indexOf('candidate') === 0;
})[0];
(r[o[k]])? r[o[k]].votes += o.votes : r[o[k]] = {candidate: o[k], votes: o.votes};
return r;
}, {}),
result = Object.keys(grouped).map(function(k){ return grouped[k]; });
console.log(result);
To get the list of names as you asked
var rawArrays = objArray1.concat(objArray2), Candidates = [], tmp = []
for (var i in rawArrays) {
tmp[rawArrays[i][Object.keys(rawArrays[i])[0]]] = 1
}
Candidates = Object.keys(tmp)
To get array with candidates and votes sum
var rawArrays = objArray1.concat(objArray2), Candidates = []
for (var i in rawArrays) {
name = rawArrays[i][Object.keys(rawArrays[i])[0]]
if (Candidates[name]) Candidates[name] += rawArrays[i].votes
else Candidates[name] = rawArrays[i].votes
}
So here I have a system that identifies the object with the highest count, however as we can see there are two objects that both have the highest count. What I want to be able to do is take the top counts, however many that may be, and output one at random. How can I do this?
var objects = [
{username: 'mark', count: 3},
{username: 'dave', count: 5},
{username: 'john', count: 5},
{username: 'lucy', count: 2},
];
var res = objects.reduce(function(resObj, obj) {
return resObj.count > obj.count ? resObj : obj
})
console.log(res);
Thanks!
Nice question here is how you can do it
Note: I added a few more of the same counts to show you how this works regardless of how many matches you have:
Working example
var objects = [
{username: 'mark', count: 3},
{username: 'dave', count: 5},
{username: 'john', count: 5},
{username: 'amy', count: 5},
{username: 'adam', count: 5},
{username: 'fenty', count: 5},
{username: 'lucy', count: 2},
];
// make an array to push same counts
var arr = [];
var res = objects.reduce(function(resObj, obj) {
// keep track of (and set) max count
var max = Math.max(resObj.count, obj.count);
// if count is equal push to our array
if (max === obj.count) {
arr.push(obj);
}
// same code as before
return resObj.count >= obj.count ? resObj : obj;
});
// get random index from our array
var randIndex = Math.floor(Math.random() * arr.length);
// get random result from our objects that have the same count:
console.log(arr[randIndex]);
Here is the answer using simple for loops. Returns random heightest object
function getHighest(objects) {
var highest = 0;
var heighestArr = [];
// first get highest index
for(var i=1; i<objects .length;i++){
if(objects[i].count > objects[highest].count){
highest= i;
}
}
// then add all the highest ones in an array
for(var i=0; i<objects .length;i++){
if(objects[i].count === objects[highest].count){
heighestArr.push(objects[i])
}
}
// return random from that array
return heighestArr[Math.floor(Math.random()*heighestArr.length)];
}
var objects = [
{username: 'mark', count: 3},
{username: 'dave', count: 5},
{username: 'john', count: 5},
{username: 'lucy', count: 2},
];
var res = objects.slice(1).reduce(function(resObj, obj) {
if (resObj[0].count > obj.count) {
return resObj;
} else if (resObj[0].count === obj.count) {
return [...resObj, obj];
} else {
return [obj]
}
}, [objects[0]])
var randomElement = function(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
console.log(randomElement(res));
Untested but this is the basic idea.
How you Convert this:
var values = [
{name:'demian', email: 'demian#gmail.com', ID: 1},
{name:'john' , email: 'john#gmail.com' , ID: 2},
{name:'mark' , email: 'mark#gmail.com' , ID: 3},
{name:'pete ' , email: 'pete#gmail.com' , ID: 4}
];
To this:
var values = [
{'demian', 'demian#gmail.com', 1},
{'john' , 'john#gmail.com' , 2},
{'mark' , 'mark#gmail.com' , 3},
{'pete ' , 'pete#gmail.com' , 4}
];
Here is a very simple solution that gets all values (as array) from a list of objects:
var data = [
{name:'demian', email: 'demian#gmail.com', ID: 1},
{name:'john' , email: 'john#gmail.com' , ID: 2},
{name:'mark' , email: 'mark#gmail.com' , ID: 3},
{name:'pete ' , email: 'pete#gmail.com' , ID: 4}
]
var values = data.map( function(d) { return [d.name, d.email, d.ID] })
console.log(values)
// output on console:
// [
// ["demian", "demian#gmail.com", 1],
// ["john", "john#gmail.com", 2],
// ["mark", "mark#gmail.com", 3],
// ["pete ", "pete#gmail.com", 4]
// ]
I hope this helps.
Edit - Here is a more generic solution:
values = data.map( function(d){ var a=[]; for(k in d) a.push(d[k]); return a })
console.log(values)
But then you need to make sure that you do not have additional properties on your objects (e.g., introduced by some JS framework). I prefer the explicit way.
For a general usage, when you not know the named-keys, or they are not the same in all the objects, you can use this script:
<script type="text/javascript">
var values = [
{name:'demian', email: 'demian#gmail.com', ID: 1},
{name:'john' , email: 'john#gmail.com' , ID: 2},
{name:'mark' , email: 'mark#gmail.com' , ID: 3},
{name:'pete ' , email: 'pete#gmail.com' , ID: 4}
];
var nrv = values.length;
var values2 = []; // to store the values, without named-keys
for(var i=0; i<nrv; i++) {
values2[i] = [];
for each(var val in values[i]) {
values2[i].push(val);
}
}
console.log(values2);
/* output on console
[["demian", "demian#gmail.com", 1],
["john", "john#gmail.com", 2],
["mark", "mark#gmail.com", 3],
["pete ", "pete#gmail.com", 4]]
*/
</script>
Try this:
var val_array = [];
for(var i in values)
{
val_array.push(
[values[i].name, values[i].email, values[i].ID]
)
}