Compare the age of the objects in an array and keep only the one with the highest age. I've gone through the solution which uses reduce function, but is there any other optimal way other than using reduce?
I am new to javascript, and still learning the concepts.
array: [ { "name": "sample", "age": 22 },{ "name": "sample2", "age": 42 }]
You can achieve this with sort:
const array = [ { "name": "sample", "age": 22 },{ "name": "sample2", "age": 42 }]
const max = array.sort((a, b) => {
return b.age - a.age
})[0]
console.log([max])
Related
I have been searching the web for this, and can only seem to locate the Object.keys(obj).length which counts the length of the JSON. I am looking to loop through the JSON and count the values which are the same. In an Array of JSON objects.
[
{
"name": "Bob",
"age": 36
},
{
"name": "Billy",
"age": 18
},
{
"name": "Bob",
"age": 45
}
]
For example, I want to count many Bob there are. I would like to then output to a component like so.
There were 2 Bob
How can this be achieved? In certain situations I will know that there could only be say 4 values for example. SITE, MOBILE, CTV, VIDEO etc, I forsee collecting them and counting them would be easier than counting a random result.
const input = [
{
"name": "Bob",
"age": 36
},
{
"name": "Billy",
"age": 18
},
{
"name": "Bob",
"age": 45
}
]
let sums = input.reduce((a, r) => {
a[r.name] ??= 0
a[r.name] ++
return a
}, {})
console.log(sums)
Now use sums variable to print data in any form you like.
I need a list of unique objects based on a specific key.
const array = [
{"name": "Joe", "age": 42},
{"name": "Donald", "age": 69},
{"name": "John", "age": 42},
]
How can i get a list of unique objects selected from the list assuming i want a list of people with unique ages.
const result = [
{"name": "Joe", "age": 42},
{"name": "Donald", "age": 69}
]
How can this be done in a performant way, is there a better way than iterating through the elements in a foreach and adding it if it does not exist in the resulting array?
One way is to feed the array to a Map where you key them by age. That will eliminate duplicates, only retaining the last in the series of duplicates. Then extract the values again from it:
const array = [{"name": "Joe", "age": 42},{"name": "Donald", "age": 69},{"name": "John", "age": 42}];
const uniques = Array.from(new Map(array.map(o => [o.age, o])).values());
console.log(uniques);
If you want to retain the first of duplicates, then first reverse the array.
Another option is to track seen values, here using a Set passed as a closure and checking for values using its .has() method to return a boolean to a filter() call. This will retain the first seen objects.
const array = [
{ "name": "Joe", "age": 42 },
{ "name": "Donald", "age": 69 },
{ "name": "John", "age": 42 },
]
const unique = (seen => array.filter(o => !seen.has(o.age) && seen.add(o.age)))(new Set());
console.log(unique)
I m trying to get all the numbers from the list of all the contacts. Im probably not using forEach correctly any advice? I've put a sample of what is expected
//sample of a contact
Object {
"company": "Financial Services Inc.",
"contactType": "person",
"firstName": "Hank",
"id": "2E73EE73-C03F-4D5F-B1E8-44E85A70F170",
"imageAvailable": false,
"jobTitle": "Portfolio Manager",
"lastName": "Zakroff",
"middleName": "M.",
"name": "Hank M. Zakroff",
"phoneNumbers": Array [
Object {
"countryCode": "us",
"digits": "5557664823",
"id": "337A78CC-C90A-46AF-8D4B-6CC43251AD1A",
"label": "work",
"number": "(555) 766-4823",
},
Object {
"countryCode": "us",
"digits": "7075551854",
"id": "E998F7A3-CC3C-4CF1-BC21-A53682BC7C7A",
"label": "other",
"number": "(707) 555-1854",
},
],
},
//Expected
numbers = [
5557664823,
7075551854
]
//does not work
const numbers = contacts.map(contact => contact.phoneNumbers.forEach(number));
forEach always returns undefined, so your map callback returns undefined, so numbers will be full of undefineds.
I think you probably want to return the phone numbers (each number in the phoneNumbers array of each entry), and then perhaps flatten the result:
const numbers = contacts.map(contact => contact.phoneNumbers.map(({number}) => number)).flat();
Array.prototype.flat is relatively new, but easily polyfilled.
That's such a common pattern that there's a flatMap method to do it in one go:
const numbers = contacts.flatMap(contact => contact.phoneNumbers.map(({number}) => number));
Or just a simple loop with push:
const numbers = [];
for (const {phoneNumbers} of contacts) {
numbesr.push(...phoneNumbers.map(({number}) => number));
}
Probably want to use reduce and map
let numbers = contacts.reduce((p, c, i) => {
return p.concat(c.phoneNumbers.map(pn => pn.number));
}, []);
I don't know how many times I've done that. forEach doesn't return anything.
const numbers = contacts.reduce((n, c)=>(a.concat(contact.phoneNumbers)),[]);
or
const numbers = contacts.reduce((n, c)=>(a.concat(contact.phoneNumbers.map(pn=>pn.number)),[]);
I recently got interested on using the spread operator syntax, so I tried some examples, I have this example of array:
var entities = [
{
"id": 1,
"age": 33,
"hobby": "games"
},
{
"id": 2,
"age": 28,
"hobby": "chess"
},
{
"id": 3,
"age": 21,
"hobby": "comics"
},
{
"age": 23,
"hobby": "games"
}
]
Then, to update all hobbies at "once" I do the following:
entities.forEach(function(entity, index) {
this[index] = {...entity, hobby: "Some String to update all hobbies"};
}, entities);
console.log(entities)
Which works but I was wondering if there's a more efficient or shorter way to achieve it while using the spread operator. Any suggestions?
EDIT:
forEach is not necessary for me, or even do it in that way, I was curious on whether the spread syntax could be used (or not) to update nested values
The spread operator doesn't really help when you're updating the list, like you do in your example. It's easier to just update the property of each object:
var entities = [ { "id": 1, "age": 33, "hobby": "games" }, { "id": 2, "age": 28, "hobby": "chess" }, { "id": 3, "age": 21, "hobby": "comics" }, { "age": 23, "hobby": "games" } ]
entities.forEach(entity => {
entity.hobby = "Some String to update all hobbies";
});
console.log(entities)
The spread operator is useful if you want to create copies of objects, like you might want to do in a .map:
var entities = [ { "id": 1, "age": 33, "hobby": "games" }, { "id": 2, "age": 28, "hobby": "chess" }, { "id": 3, "age": 21, "hobby": "comics" }, { "age": 23, "hobby": "games" } ]
const newEntities = entities.map(entity =>
({...entity, hobby: "Some String to update all hobbies"})
);
console.log(newEntities)
The spread operator will iterate over all keys in the object to copy them and their values into the new object. If you want more efficiency, don't use the spread operator. Just assign directly to each object as you iterate over the list:
entity.hobby = "Some String to update all hobbies"
Note that this modifies the object in the existing array. So you don't need to assign this[index]. Alternatively, you can use map() instead of foreach() to return a new array that is created from the existing array.
Not sure if spread operator is really needed for what you are doing?
You can also look into this link for some interesting usage of the spread, Array.from and rest operator.
More into just spread operator here.
If you are looking for a fancier/smaller way to write this, here's two, one that uses uses .map and spread to return a copy of entities, and another that uses .forEach and updates the same array entities:
const COMMON_HOBBY = 'Coding';
let entities = [{
"id": 1,
"age": 33,
"hobby": "games"
},
{
"id": 2,
"age": 28,
"hobby": "chess"
}];
// To assign to new array (copy)
let output = entities.map((entity) => ({...entity, hobby: COMMON_HOBBY }));
console.log(output);
// Mutate /edit same array entities
entities.forEach((entity) => entity.hobby = COMMON_HOBBY );
console.log(entities);
I have an array of objects like the following :
var array = {
"112" : {
"id": "3",
"name": "raj"
},
"334" : {
"id": "2",
"name": "john"
},
"222" : {
"id": "5",
"name": "kelvin"
}
}
Now i want to sort the array in ascending order of id and then restore it in array. I tried using sort() but could not do it. Please help how to do so that when i display the data from the array it comes sorted.
Assuming you meant your code to be an array of objects, ie:
var unsortedArray = [
{ id: 3, name: "raj" },
{ id: 2, name: "john" },
{ id: 5, name: "kelvin" }
];
Then you would be able to sort by id by passing a function to Array.sort() that compares id's:
var sortedArray = unsortedArray.sort(function(a, b) {
return a.id - b.id
});
As others have pointed out, what you have is an object containing objects, not an array.
var array = {
"112" : {
"id": "3",
"name": "raj"
},
"334" : {
"id": "2",
"name": "john"
},
"222" : {
"id": "5",
"name": "kelvin"
}
}
var sortedObject = Array.prototype.sort.apply(array);
result:
{
"112": {
"id": "3",
"name": "raj"
},
"222": {
"id": "5",
"name": "kelvin"
},
"334": {
"id": "2",
"name": "john"
}
}
That isn't an array, it is an object (or would it if it wasn't for the syntax errors (= should be :)). It doesn't have an order.
You could use an array instead (making the current property names a value of a key on the subobjects).
Alternatively, you could use a for loop to build an array of the key names, then sort that and use it as a basis for accessing the object in order.
JavaScript objects are unordered by definition. The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
That is an object but you can sort an array ilke this:
Working Demo: http://jsfiddle.net/BF8LV/2/
Hope this help,
code
function sortAscending(data_A, data_B)
{
return (data_A - data_B);
}
var array =[ 9, 10, 21, 46, 19, 11]
array.sort(sortAscending)
alert(array);
Not many people knows that Array.sort can be used on other kinds of objects, but they must have a length property:
array.length = 334;
Array.prototype.sort.call(array, function(a, b) {return a.id - b.id;});
Unfortunately, this doesn't work well if your "array" is full of "holes" like yours.