Find single value from multiple values in single array - javascript

I have a single array having multiple values in that as shown in code below.
tempstraindatasource
tempstraindatasource[0] = {
A = "0",
B = "1",
C = "2",
D = "3"
}
tempstraindatasource[1] = {
A = "4",
B = "5",
C = "6",
D = "7"
and so on like wise I have many data exist in single array
}
I want to do one procedure that finds the data are consist or not in single line like I want to find Species having name "A" = "0" or any value "B" = "0" or "C" = "0"! How can I do it in single line? Please some one help me to do this.
Thanks in advance and appreciate as well.

You could use Array#forEach for the array and check if any of the properties have the value, you need with Array#some, and push the index then to the result array.
var data = [{ a: 0, b: 1, c: 2, d: 3 }, { a: 4, b: 5, c: 6, d: 7 }],
indices = [];
data.forEach(function (a, i) {
Object.keys(a).some(function (k) {
return a[k] === 0;
}) && indices.push(i);
});
console.log(indices);

As stated in comments your question needs editing (or better a total rewrite) but I think what you need is this
var fruits = [{name: 'banana', cost: 5}, {name: 'apple', cost:2}];
var filteredArray = fruits.map(function(fruit, index){
fruit.index = index;
return fruit;
}).filter(function(fruit){
return fruit.name === 'banana';
});
document.write(JSON.stringify(filteredArray));

Related

Top highest values in an object (more if there are more max values and they are the same)

Lets suppose I have object like this:
var obj = {a : 5, b : 10, c : 15, d : 20, e : 20, f : 25};
I would like to get top 3 highest values - notice that d and e key have the same value and I need to get the keys also, so it would looks like:
Highest values:
f - 25
d - 20
e - 20
also if there are for example six values and four are identical:
var obj2 = {a:1, b:1, c:1, d:1, e:0,8, f: 0,5};
I need to show 4 highest.
Highest values:
a-1
b-1
c-1
d-1
I guess there is need to iterate over ALL object properties to get Math.max, but I also need a something to count 3 max numbers WITH their keys, and if there is more max (all the same) I need to "get them all!".
EDIT: there are great answers atm, so I guess I will not finish this code and just use given examples :)
This is an example implementation, with annotations to explain what is happening at each step.
function maxValues(o, n) {
// Get object values and sort descending
const values = Object.values(o).sort((a, b) => b - a);
// Check if more values exist than number required
if (values.length <= n) return o;
// Find nth maximum value
const maxN = values[n - 1];
// Filter object to return only key/value pairs where value >= maxN
return Object.entries(o)
.reduce((o, [k, v]) => v >= maxN ? { ...o, [k]: v } : o, {});
}
const a = maxValues({
a: 5,
b: 10,
c: 15,
d: 20,
e: 20,
f: 25
}, 3);
console.log(a);
const b = maxValues({
a: 1,
b: 1,
c: 1,
d: 1,
e: 0.8,
f: 0.5
}, 3);
console.log(b);
const c = maxValues({
a: 5,
b: 10,
}, 3);
console.log(c);
The callback passed to the Array.prototype.reduce function can be expanded out to the following:
return Object.entries(o)
.reduce(function (obj, [key, value]) {
if (v >= maxN) {
return Object.assign(obj, {
[key]: value
});
} else {
return obj;
}
}, {});
Instead, I condensed it down using an Arrow Function Expression, ternary operator, and spread syntax.
The ternary operator is essentially shorthand for an if/else statement. E.g.
condition ? true : false;
// or
v >= maxN ? { ...o, [k]: v } : o;
The spread syntax allows an iterable value to be expanded in place. In this instance, it's being used to copy existing key/value pairs from one object literal to another.
const a = { first_name: 'Rob', gender: 'male' };
const b = { ...a, username: 'fubar' };
console.log(b); // { first_name: 'Rob', gender: 'male', username: 'fubar' };
Simply,
Sort the object based on its values using, Object.entries
Get the least value you can filter.
Filter the entries and return as Object using Object.fromEntries.
function getTopValues(obj, topN)
{
var sortedEntries = Object.entries(obj).sort(function(a,b){return b[1]-a[1]});
var last = sortedEntries[topN-1][1];
var result = sortedEntries.filter(function(entry){
return entry[1] >= last;
});
console.log(Object.fromEntries(result));
}
getTopValues({a:5, b:10, c:15, d:20, e:20, f:25}, 3);
getTopValues({a:1, b:1, c:1, d:1, e:0.8, f: 0.5}, 3);
getTopValues({a:1, b:1, c:1, d:1, e:0.8, f: 0.5}, 5);
So, you want to find the top 3 highest and if there are multiple identical highest then you want to include all of that.
This problem is asked in a slightly weird fashion.
I am going to assume that if there is something like a:1 b:1 c:2 d:2 e:3,
you would like to include a,b,c and d.
First of all, you only have to keep track of the keys because you can get the values instantly at the end.
Ok! Let's start. (efficient but ugly)
class Numandamount {
constructor(number, amount) {
this.number = number;
this.amount = amount;
}
}
//That's just a class to link numbers and their amounts
var numtoamount = [];
//Now let's fill that array!
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var num = obj.property;
var found = false;
for(Numandamount naa in numtoamount){
if(naa.number == num){
naa.amount++;
found = true;
}
}
if(!found){
naa.push(new Numandamount(num,1));
}
}
}
//The array is done!
numtoamount.sort(function(a,b){return b.number-a.number});
//Now all we have to do is loop through it!
var count = 0; // keep track of how many we did
var i = 0;
while(count<4 && i<numtoarray.length){
count += numtoamount[i].amount;
i++;
}
//BOOOM WE DID IT
// I is the biggest index so all we have to do is:
for(var j = 0;j<i;j++){
console.log("We have "+numtoamount[j].amount+" "+numtoamount[j].number+"'s");
}
For eg. it will print out for this example obj: {a:1 b:1 c:4 d:6 e:7 f:4}
We have 1 7's
We have 1 6's
We have 2 4's
If you would like some other implementation please comment below!
I put my heart into this <3
I would start with transforming your object into an array of objects:
const arr = []
for (var key in obj){
arr.push( {[key]: obj[key]} )
}
Now you have an array that looks like this:
[
{"f": 25},
{"d": 20},
{"e": 20},
{"c": 15},
{"b": 10},
{"a": 5}
]
Now you can sort your objects by the magnitude of their values:
const sortedArray = arr.sort( (a,b) => {
if (Object.values(a)[0] > Object.values(b)[0]) {
return -1
}
})
Which would give:
[
{"f": 25},
{"d": 20},
{"e": 20},
{"c": 15},
{"b": 10},
{"a": 5}
]
Then you can just pick however many values off the top you want. For example
sortedArray.filter( (item, index) => {
if (index <= 2 || Object.values(item)[0] === Object.values(sortedArray[0])[0]) {
return item
}
})
Which gives:
[
{"f": 25},
{"d": 20},
{"e": 20}
]
Or in the case of your second object, it would match the n highest values, but also grab any other values that are equal to the highest value.
As a single function:
function sortYourObject(object, number){
var arr = []
for (var key in object){
arr.push( {[key]: object[key]} )
}
const sortedArray = arr.sort( (a,b) => {
if (Object.values(a)[0] > Object.values(b)[0]) {
return -1
}
})
const endresult = sortedArray.filter( (item, index) => {
if (index <= 2 || Object.values(item)[0] === Object.values(sortedArray[0])[0]) {
return item
}
})
return endresult
}

_.sum(_.values(x)) ,if x's values are not all numbers

I have an object similar to this :
obj = { name:"myobject", MON: 3, TUE: 5}
I am trying to do a _.sum(_.values(obj)) and push that value into an array this.hours.push(_.sum(_.values(obj))) .
I am expecting an array like this [8](the reason I want to store it inside array is because I might want to parse multiple objects in the future). How do I achieve this?
Filter out the non-numbers.
const obj = { name: "myobject", MON: 3, TUE: 5 };
const numbers = _.filter(obj, x => typeof x === 'number');
const total = _.sum(numbers);
Just in case anyone need it, Adding regular way to do this apart from #mbojko answer:
const obj = { name: "myobject", MON: 3, TUE: 5 };
var total = 0;
_.forOwn(obj, function(value) {
if(typeof value === 'number')
total += value;
});
You can use _.sumBy() and return 0 for non numeric values:
const obj = { name:"myobject", MON: 3, TUE: 5}
const result = _.sumBy(_.values(obj), v => _.isNumber(v) ? v : 0)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Return object with highest key/value pairs from an array of objects

Given an array of objects, I want to return an object with the highest values from all the objects.
let countObj = [{2:1},{2:4, 5:1},{3:3}]
let finalObj = {}
let primes = [2,3,5]
// finalObj should return {2:4, 3:3, 5:1}
I feel like there should be some way to use the primes array and reduce on the countObj to get the desired result.
primes.forEach(p => countObj.reduce((a,b) =>{
if (a[p]){ //if prime no. exists as key in a
a[p] > b[p] ? //keep key/val pair in a : replace key/val pair
}else{ //if new prime is not a key in a
a[p] = b[p]
}
},{})
I'm not sure if the logic is correct and also, I don't know how to get it to return the final object.
You could check if the stored value is greater than the actual value and if not, then assign the value to the result set.
var countObj = [{ 2: 1 }, { 2: 4, 5: 1 }, { 3: 3 }],
finalObj = {};
countObj.forEach(o => Object.keys(o).forEach(k => finalObj[k] > o[k] || (finalObj[k] = o[k])));
console.log(finalObj); // { 2:4, 3: 3, 5: 1 }
With primes
var countObj = [{ 2: 1 }, { 2: 4, 5: 1 }, { 3: 3 }],
finalObj = {},
primes = [2, 3, 5]
countObj.forEach(o => primes.forEach(k => k in o && (finalObj[k] > o[k] || (finalObj[k] = o[k]))));
console.log(finalObj); // { 2:4, 3: 3, 5: 1 }
Be careful with your tests: 0 is the same as a missing value. And when using reduce, you must return the accumulator object.
I'd reduce on the objects instead of reducing on the primes:
let finalObj = countObj.reduce((f, o)=>{
primes.forEach(k=>{
if (k in o && !(o[k]<f[k])) f[k]=o[k];
});
return f;
}, {});
You can use a nested foreach like this.
In this case you do not need primes[]
let countObj = [{
2: 1
}, {
2: 4,
5: 1
}, {
3: 3
}];
let finalObj = {};
let primes = [2, 3, 5];
countObj.forEach(function(obj) {
Object.keys(obj).forEach(function(key) {
var finalObjValue = finalObj[key] || 0;
if(obj[key] > finalObjValue)
finalObj[key] = obj[key];
});
});
console.log(finalObj);

Getting key with the highest value from object

I have a object like that one:
Object {a: 1, b: 2, undefined: 1}
How can I quickly pull the largest value identifier (here: b) from it? I tried converting it to array and then sorting, but it didn't work out, since it got sorted alphabetically (and it seems like a overkill to juggle data back and forth just for getting one value out of three).
For example:
var obj = {a: 1, b: 2, undefined: 1};
Object.keys(obj).reduce(function(a, b){ return obj[a] > obj[b] ? a : b });
In ES6:
var obj = {a: 1, b: 2, undefined: 1};
Object.keys(obj).reduce((a, b) => obj[a] > obj[b] ? a : b);
Using Underscore or Lo-Dash:
var maxKey = _.max(Object.keys(obj), function (o) { return obj[o]; });
With ES6 Arrow Functions:
var maxKey = _.max(Object.keys(obj), o => obj[o]);
jsFiddle demo
Here is a suggestion in case you have many equal values and not only one maximum:
const getMax = object => {
return Object.keys(object).filter(x => {
return object[x] == Math.max.apply(null,
Object.values(object));
});
};
This returns an array, with the keys for all of them with the maximum value, in case there are some that have equal values.
For example: if
const obj = {apples: 1, bananas: 1, pears: 1 }
//This will return ['apples', 'bananas', 'pears']
If on the other hand there is a maximum:
const obj = {apples: 1, bananas: 2, pears: 1 }; //This will return ['bananas']
---> To get the string out of the array: ['bananas'][0] //returns 'bananas'`
Supposing you've an Object like this:
var obj = {a: 1, b: 2, undefined: 1}
You can do this
var max = Math.max.apply(null,Object.keys(obj).map(function(x){ return obj[x] }));
console.log(Object.keys(obj).filter(function(x){ return obj[x] == max; })[0]);
{a: 1, b: 2, undefined: 1}
The best work around I've seen is this
const chars = {a: 1, b: 2, undefined: 1}
//set maximum value to 0 and maxKey to an empty string
let max = 0;
let maxKey = "";
for(let char in chars){
if(chars[char]> max){
max = chars[char];
maxKey= char
}
}
console.log(maxKey)
Very basic method. might be slow to process
var v = {a: 1, b: 2, undefined: 1};
function geth(o){
var vals = [];
for(var i in o){
vals.push(o[i]);
}
var max = Math.max.apply(null, vals);
for(var i in o){
if(o[i] == max){
return i;
}
}
}
console.log(geth(v));
Combination of some ideas from other answers. This will get all the keys with the highest value, but using the spread operator to get the maximum value and then filter array method:
const getMax = object => {
let max = Math.max(...Object.values(object))
return Object.keys(object).filter(key => object[key]==max)
}
let obj = {a: 12, b: 11, c: 12};
getMax(obj)
let data = {a:1,b:2,undefined:3}
let maxValue = Object.entries(data).sort((x,y)=>y[1]-x[1])[0]
note: this is a very expensive process and would block the event loop if used with objects of large sizes(>=1000000). with large array slice the entries and call the above method recurrently using setTimeout.
If you need to return an array from an object with the keys for all duplicate properties with the (same or equal) highest value, try this:
const getMax = Object.keys(object)
.filter(x => {
return object[x] == Math.max.apply(null,
Object.values(object));
})
var object = { orange: 3, blue: 3, green: 1}
console.log(getMax) // ['orange', 'blue']

Merge two arrays as if shuffling cards without iterating?

In javascript, is there an easy way to merge 2 arrays as if shuffling a deck of cards?
For example:
[ "1", "2", "3" ] +
[ "a", "b", "c" ]
=> [ "1", "a", "2", "b", "3", "c" ]
This action is typically called "zip".
Underscore.js has an implementation of it:
var a1 = [ "1", "2", "3" ];
var a2 = [ "a", "b", "c" ];
var zipped = _.zip(a1, a2);
If you want a random order, you can use shuffle:
var shuffled = _.shuffle(a1.concat(a2));
var arr1 = ["1", "2", "3"];
var arr2 = ["a", "b", "c"];
You can just loop through the arrays and create a new one. This example assumes that arr1 and arr2 are the same length.
var result = (function(a, b){
for(var i = 0, result = []; i < a.length; i++)
result.push(a[i], b[i]);
return result;
})(arr1, arr2);
// result == ["1", "a", "2", "b", "3", "c"]
You can't do it without iterating, but you can hide the iteration behind some array functions.
var a = [ "1", "2", "3" ];
var b = [ "a", "b", "c" ];
// only works if a and b have the same length
var c = a.concat(b).map(function(item, index, arr){
return index % 2 ? arr[arr.length/2 + (index+1)/2 - 1] : arr[index/2];
});
console.log(c);
You can create a closure that can be used as an array for reading (i.e. c(i) returns i-th element of result):
c = function(i){ return [a, b][i & 1][i >> 1]; };
or, probably more efficient, as
c = function(i){ return (i & 1) ? b[i >> 1] : a[i >> 1]; };
The nice thing of this approach is that you don't build all elements at once, but you will just get the element from the original arrays only if requested.
This also allows using functions instead of arrays for a and b:
c = function(i){ return (i & 1) ? b(i >> 1) : a(i >> 1); };

Categories