Find minimum in array of dictionaries? [duplicate] - javascript

This question already has answers here:
Finding the max value of an attribute in an array of objects
(21 answers)
Compare JavaScript Array of Objects to Get Min / Max
(17 answers)
Closed 2 months ago.
I have something like :
var array = [
{'a':3,'b':4},
{'a':1,'b':8},
{'a':9,'b':7}]
What is an elegant one line to find the min/max of the key 'a' (max=9, min = 1) ?
I know it is simple but i couldn't find a one line solution only loops.

Logic
Create a simple array of the required nodes.
Use Math.max with the spread syntax to get the maximum.
const array = [{ a: 3, b: 4 },{ a: 1, b: 8 },{ a: 9, b: 7 }];
const max = Math.max(...array.map(({ a }) => a));
console.log(max);
Apply the same logic for min as well and use Math.min
const array = [{ a: 3, b: 4 },{ a: 1, b: 8 },{ a: 9, b: 7 }];
const nodes = array.map(({ a }) => a);
const maxMin = { max: Math.max(...nodes), min: Math.min(...nodes)};
console.log(maxMin);

you can do something like this
var array = [
{ a: 3, b: 4 },
{ a: 1, b: 8 },
{ a: 9, b: 7 },
];
const arrayA = array.map((v) => v.a);
const maxA = Math.max(...arrayA);
const minA = Math.min(...arrayA);
console.log({ minA, maxA });

Tried to keep it in 1 line.
var array = [
{ a: 3, b: 4 },
{ a: 1, b: 8 },
{ a: 9, b: 7 },
];
const result = {
min: Math.min(...array.map((x) => x.a)),
max: Math.max(...array.map((x) => x.a)),
};
console.log(result);

Related

Dynamically sort object by key provided in a variable

What's wrong with this code? Why cant it sort the array according to the a key of the object?
It works when using dot notation in the condition but I want to use the second parameter in the condition instead of dot notation. Please help me getting the result.
This works:
if (objSort[i][`sortBy`] > objSort[j][`sortBy`]) {
[objSort[i], objSort[j]] = [objSort[j], objSort[i]]
}
This does not work:
function sortData(objSort, sortBy) {
for (let i = 0; i < objSort.length; i++) {
for (let j = i + 1; j < objSort.length; j++) {
if (objSort[i][`sortBy`] > objSort[j][`sortBy`]) {
[objSort[i], objSort[j]] = [objSort[j], objSort[i]]
}
}
}
console.log(data);
}
const data = [{ a: 4, b: 5 }, { a: 1, b: 10}, { a: 2, b: 5 }, { a: 14, b: 15 }, { a: 12, b: 3 }];
sortData(data,'a');
sortBy is your variable name, so remove it from the template literal:
if (objSort[i][sortBy] > objSort[j][sortBy]) {
That being said, your code is much more complex than it needs to be - there's no need for two loops and reorganising the array - just use sort():
const sortData = (objSort, sortBy) => objSort.sort((a, b) => a[sortBy] - b[sortBy]);
const data = [{ a: 4, b: 5 }, { a: 1, b: 10}, { a: 2, b: 5 }, { a: 14, b: 15 }, { a: 12, b: 3 }];
const result = sortData(data,'a');
console.log(result);

How can I transform the Object in this Array of Objects? [duplicate]

This question already has answers here:
Changing the key name in an array of objects?
(11 answers)
Closed 1 year ago.
Given this array of objects:
arrayBefore: [
{
a: "string1",
b: 10,
},
{
a: "string2",
b: 20,
},
]
how can one change the keys using JavaScript for the end result of:
arrayAfter: [
{
x: "string1",
y: 10,
},
{
x: "string2",
y: 20,
},
]
You can use Array.prototype.map to transform the objects.
const arrayBefore = [{
a: "string1",
b: 10,
},
{
a: "string2",
b: 20,
},
]
const arrayAfter = arrayBefore.map((item) => ({
x: item.a,
y: item.b,
}))
console.log(arrayAfter)

return object in an array with the most props

Say I have an array of objects like this:
const arr = [
{ a: 1, b: 2, c: 3, d: 4 },
{ a: 1 },
{ a: 1, b: 2, c: 3 },
{ a: 1, b: 2 }
];
How can I return the object with the most properties/keys? Preferably using in an efficient and terse manner using higher order functions.
You could assign to a single object.
const
array = [{ a: 1, b: 2, c: 3, d: 4 }, { a: 1 }, { a: 1, b: 2, c: 3 }, { a: 1, b: 2 }],
object = Object.assign({}, ...array);
console.log(object);
If you have different values, you could reduce the array.
const
array = [{ a: 1, b: 2, c: 3, d: 4 }, { a: 1 }, { a: 1, b: 2, c: 3 }, { a: 1, b: 2 }],
object = array.reduce((a, b) => Object.keys(a).length > Object.keys(b).length
? a
: b
);
console.log(object);
You can get the number of keys from an object by calling Object.keys(obj) and then checking it's length property.
With that, you could reduce the array by checking each pair of objects and return the one with the most keys as a one liner:
const biggestObject =
arr.reduce((a, b) => Object.keys(a).length > Object.keys(b).length ? a : b);

How to sort array by two linked fields? JS [duplicate]

This question already has answers here:
Javascript - Sort Array of objects by 2 Properties
(4 answers)
Closed 4 years ago.
There is a simple part of the code where I need to sort an array of objects by the next way (sorting array objects by a prop first and then by the b prop). So the result should look's like:
var a = [
{
a: 1,
b: 2
},
{
a: 1,
b: 4
},
{
a: 1,
b: 5
},
{
a: 2,
b: 1
},
{
a: 2,
b: 3
},
{
a: 2,
b: 4
}
]
But unfortunately, my code below doesn't seem to work well. Could someone help me? Thank you in advance.
var a = [
{
a: 2,
b: 4
},
{
a: 2,
b: 3
},
{
a: 1,
b: 2
},
{
a: 1,
b: 4
},
{
a: 1,
b: 5
},
{
a: 2,
b: 1
}
]
a.sort((first, second) => first.a - second.a && first.b - second.b ? 1 : -1)
console.log(a)
You need to check the first property a if they are equal then go for b.
const a = [{"a":2,"b":4},{"a":2,"b":3},{"a":1,"b":2},{"a":1,"b":4},{"a":1,"b":5},{"a":2,"b":1}];
a.sort((obj1 ,obj2) => obj1.a - obj2.a ? obj1.a - obj2.a : obj1.b -obj2.b );
console.log(a);

Return an Array of Arrays containing objects that share a common value in a property

Say I have an array of 3 objects like this:
[
{
a: 4,
b: 5,
c: 4
},
{
a: 3,
b: 5,
c: 6
},
{
a: 2,
b: 3,
c: 3
}
]
I would like to return an array of arrays containing the objects that share a common value for the property b. So the resulting array would contain only one array containing 2 objects like this:
[
[
{
a: 4,
b: 5,
c: 4
},
{
a: 3,
b: 5,
c: 6
}
]
]
How would I do this?
You could do this with map and filter
var data = [{"a":4,"b":5,"c":4},{"a":3,"b":5,"c":6},{"a":2,"b":3,"c":3}];
var check = data.map(e => {return e.b});
var result = [data.filter(e => { return check.indexOf(e.b) != check.lastIndexOf(e.b)})];
console.log(result)
To group multiple objects in separate arrays with same b values you can use map and forEach
var data = [{"a":4,"b":5,"c":4},{"a":3,"b":5,"c":6},{"a":2,"b":3,"c":3}, {"a":3,"b":7,"c":6},{"a":2,"b":7,"c":3}], result = [];
var check = data.map(e => {return e.b});
data.forEach(function(e) {
if(check.indexOf(e.b) != check.lastIndexOf(e.b) && !this[e.b]) {
this[e.b] = [];
result.push(this[e.b]);
}
(this[e.b] || []).push(e);
}, {});
console.log(result)
This proposal uses a single loop with Array#forEach but without Array#indexOf.
var array = [{ a: 4, b: 5, c: 4 }, { a: 3, b: 5, c: 6 }, { a: 2, b: 3, c: 3 }],
grouped = [];
array.forEach(function (a) {
this[a.b] = this[a.b] || [];
this[a.b].push(a);
this[a.b].length === 2 && grouped.push(this[a.b]);
}, Object.create(null));
console.log(grouped);
You can create a function that accepts fulfillment criteria and will return as many nested arrays as rules passed.
Let's say you have an array of objects, arr.
var arr = [{a: 1, b: 2}, {a: 3, b: 2}, {a: 3, b: 4}, {a: 1, b: 1}]
And you want to return an array with with nested arrays that fulfill a particular requirement, let's say you want objects with an a:1 and b:2.
You can create a function that loops through your rules and creates a nested array with the objects that fulfill each rule.
For example:
var arr = [{a: 1, b: 2}, {a: 3, b: 2}, {a: 3, b: 4}, {a: 1, b: 1}]
function makeNestedArrays() {
var rules = [].slice.call(arguments);
return rules.reduce(function(acc, fn) {
var nestedArr = [];
arr.forEach(function(obj) {
if (fn(obj)) {
nestedArr.push(obj);
}
});
// only push nested array
// if there are matches
if (nestedArr.length) {
acc.push(nestedArr);
}
return acc;
}, []);
}
var result = makeNestedArrays(
function(obj) { return obj.a === 1; },
function(obj) { return obj.b === 2; }
);
console.log(result);
This allows you to pass as many "rules" as you want, and will create a nested array for each rule so long as there is at least one match.
You could use a Map to group them, this should work with any kind of value (just be sure the equality rules check out):
var arr = [{
a: 4,
b: 5,
c: 4
}, {
a: 3,
b: 5,
c: 6
}, {
a: 2,
b: 3,
c: 3
}];
var result = arr.reduce(function(m, o){
var value = o.b;
if(m.has(value)){
m.get(value).push(o);
} else {
m.set(value, [o]);
}
return m;
}, new Map());
console.log(...(result.values()));
If you'd need to filter out the groups of 1:
var arr = [{
a: 4,
b: 5,
c: 4
}, {
a: 3,
b: 5,
c: 6
}, {
a: 2,
b: 3,
c: 3
}];
var result = arr.reduce(function(m, o){
var value = o.b;
if(m.has(value)){
m.get(value).push(o);
} else {
m.set(value, [o]);
}
return m;
}, new Map());
result = [...result.values()].filter(a => a.length > 1);
console.log(result);

Categories

Resources