How to get max string from objects of array - javascript

i need to get length of string by two property of bjects.
data:
[ {
Country Code : 'CZ',
Country : 'El Salvador'
},{
Country Code : 'SVY',
Country : 'Czech'
} ]
how to get 'Country: 'El Salvador' and Country Code: 'SVY'

To get the length of each in your object literal, use .length inside a loop as below
for (var i = 0; i < data.length; i++){
var countryLen = data[i].country.length; //11 5
var countryCodeLen = data[i].countryCode.length; //2 3
}
If however, you are trying to return the longest string in your object, see below
var maxLen = Math.max.apply(Math, data.map(function (o) { return o.countryCode.length }));
For more information on .map() see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

The following is a solution that uses reduce; note that all objects in arr must contain the property propName.
let longestStr = (arr, prop) =>
arr.reduce( (p,c) => p.length > c[prop].length ? p : c[prop] , '' )
longestStr is a function which takes an array arr and a property name prop, which should be a string. For an in-depth discussion of how reduce works, I would recommend the excellent MDN reference.

Related

Return the key from a JavaScript array?

Using PHP I can return the key by looking up the value inside an array.
<?php
$array = array(
'fruit1' => 'apple',
'fruit2' => 'orange',
'fruit3' => 'grape',
'fruit4' => 'apple',
'fruit5' => 'apple');
while ($fruit_name = current($array)) {
if ($fruit_name == 'apple') {
echo key($array).'<br />';
}
next($array);
}
?>
But I'm learning javascript, I've searched and haven't found a solution, I'm still a beginner.
How can I return the key by fetching the value within a given array?
I've already tried using its functions: .indexOf() or .findIndex()
var array = [];
array['key'] = 'Value';
array['car'] = 'Ferrari';
array['car2'] = 'BMW';
console.log(key='Ferrari'??);
How to Return 'car' if Value = 'Ferrari' ?
another doubt in this case is it better to use Array or Class? Is it possible to return the class key?
var pessoas = {'car': 'Ferrari', 'car2':'BMW'};
Arrays don't have keys, only numeric indexes. When you pass a string to an Array, you are actually creating a new property for the Array object, not a new item in the Array data (for example, .length is a property of an Array, not an indexed value).
var array = [];
// The following 3 lines don't create indexed values in the array:
array['key'] = 'Value';
array['car'] = 'Ferrari';
array['car2'] = 'BMW';
// Which is proven here:
console.log(array.length); // 0
// What they do is create new properties on the Array instance:
console.log(array.car2); // "BMW"
If you need keys, use an object, which is structured as follows:
{key: keyValue, key: keyValue, key:keyValue ...}
where the key is always a string, so quotes around the key name are not necessary.
var pessoas = {car: 'Ferrari', car2:'BMW'};
console.log("The second car is: " + pessoas.car2);
console.log("The keys and key names are: ");
for (var prop in pessoas){
console.log(prop + " : " + pessoas[prop]);
}
You should use Objects instead of arrays in JavaScript to store PHP equivalent of arrays with keys. In JS if you make an array, add non numeric keys to it and then do .length it will give 0. So many built in functions do not work, like .filter .find and .map.
//your way
let pessoas = [];
pessoas ["car1"] = "Ferrari";
pessoas ["car2"] = "BMW";
//the safe way. Both ways work.
pessoas = {'car': 'Ferrari', 'car2':'BMW'};
function getObjKey(obj, value) {
return Object.keys(obj).find(key => obj[key] === value);
}
console.log(getObjKey(pessoas, 'BMW'));
Additionally, you can turn string-keyed arrays into object like this:
function getObjKey(obj, value) {
return Object.keys(obj).find(key=>obj[key] === value);
}
var arrayToObject = (array)=>Object.keys(array).reduce((acc,curr)=>(acc[curr] = array[curr],
acc), {});
let pessoas = [];
pessoas["car1"] = "Ferrari";
pessoas["car2"] = "BMW";
pessoas.push("corretArray");
pessoas = arrayToObject(pessoas);
console.log(getObjKey(pessoas, 'BMW'));

Combining two arrays into an object

I have two arrays one with label date i.e [Date, Date, Date ...] and
the other with the actual date data i.e [2021-11-26, 2021-11-25, ...].
I want to combine these two arrays such that I get array of objects such as [ { Date: 2021-11-26}, {Date:2021-11-25}, {..}, ...].
I have tried these two methods
obj = {};
for (var i = 0, l = date_label.length; i < l; i += 1) {
obj[date_label[i]] = data_date[i]
}
console.log(obj);
and
_.zipObject(date_label, data_date);
However it only ends up giving me the last date of my data set, in an object data structure ie { Date: 1999-11-24}
The keys inside an object / associative array are unique. Your obj is such a thing. If you turn it into a regular array and push new objects into it, it will work.
const obj = [];
for (let i = 0, l = date_label.length; i < l; i++) {
obj.push({[date_label[i]]: data_date[i]})
}
console.log(obj);
You should probably assert that both your arrays have the same length.
The issues you are facing is that your date_label are the same and the loop are replacing the dates on the same label, again and again, you just need to change the label name and give unique to each one or you change them into the loop as well like this (obj[date_label[i] + str(i)] = data_date[i]).
date_label = ['date1', 'date2', 'date3', .....]
obj = {};
for (var i = 0, l = date_label.length; i < l; i += 1) {
obj[date_label[i]] = data_date[i]
}
console.log(obj);
obj is of type array not object.
data_date needs to be in string format.
for(var i= 0; i<data_date.length-1;i++) {
obj.push({"Date":date_date[i]}) }
with array reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
var myFinalArray = data_date.reduce(
(previousValue, currentValue, currentIndex, array) => ({
currentValue: date_label[currentIndex]
}), {});
Hello AshleyCrasto,
Welcome to Stackoverflow.
Sol : Well, the other members have given solution on how to achieve the desired result. I will emphasize on why you are getting the single object.
it only ends up giving me the last date of my data set, in an object data structure ie { Date: 1999-11-24}
You need to understand how references work in JavaScript. Heres the catch,
As the values in date_label are all same
[Date, Date, Date ...]
When you use,
obj[date_label[i]] = data_date[i]
Everytime, it get executed the same key value will be keep updating instead of creating new key and new value. Because the same values holds same reference.
So, first time {"date" : "somevalue"} will be there, then
second time {"date" : "somevalue2"}, the value of key "date" will be updated
with new value. This is due to same key.
Therefore, you need to take of this thing. For your better understanding here is my code: (same as others but elaborately)
const date_label = ["date","date"]
const data_date = [2021-11-26, 2021-11-25]
function returnObj(label, value){
//this will return a new object with provided label and value.
const Obj = {};
Obj[label] = value
return Obj
}
let listOfObjects = []
for(let i=0 ; i< date_label.length ; i++){
//new object will be added to list.
const obj = returnObj(date_label[i],data_date[i])
listOfObjects.push(obj)
}
console.log(listOfObjects)

Jquery check if one array contains same value

I have an simple javascript array that may contain duplicates or maynot contain duplicates.
var names = [
['aaa','pin/test1.html'],
['bbb','pin/test2.html'],
['ttt','test.html'],
['ggg','test.html'],
['yyy','un/777.html'],
['ggg','test3.html'],
['nnn','test3.html'],
['eee','n/777.html'],
['sss','pin/test1.html'],
['xxx','pin/test2.html'],
['ppp','pin/test1.html'],
];
I need to find the duplicate filepath and put their name into new array. If there is no duplicate then assign its name in first and then assign '' after two values. I could point all the codes that I have tried but it doesnt work. I accept jquery solution also. The expected outcome is this.
var outcome = [
[['aaa','sss','ppp'], 'pin/test1.html'],
[['bbb','eee','xxx'], 'pin/test2.html'],
[['ttt','ggg',''], 'test.html'],
[['yyy','',''], 'un/777.html'],
[['ggg','nnn',''], 'test3.html'],
];
What I have tried is this
for (var i = 0; i < arr.length; i++) {
var uniqueNames = [];
$.each(arr[i], function (i, el) {
if ($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});
console.log(uniqueNames);
}
You could take a hash table and an array of empty strings and find the next slot for the value.
The array is reduced by taking an object as accumulator and a destructure array as value (the first part of the array) and key (the second part, aka filepath).
Inside of Array#reduce, a property check with the key is made and if undefined, an array with the wanted structure (array with two items, the first is an array with three emty spaces and the key) is being assigned by using a logical nullish assignment ??=.
The next line assigns the value to the next free slot, an item with an empty string.
Finally the accumulator is returned.
To get only an array as result, a conversion of the values of the object takes place.
let names = [['aaa','pin/test1.html'], ['bbb','pin/test2.html'], ['ttt','test.html'], ['ggg','test.html'], ['yyy','un/777.html'], ['ggg','test3.html'], ['nnn','test3.html'], ['eee','n/777.html'], ['sss','pin/test1.html'], ['xxx','pin/test2.html'], ['ppp','pin/test1.html']],
grouped = Object.values(names.reduce((r, [v, k]) => {
r[k] ??= [Array(3).fill(''), k];
r[k][0][r[k][0].indexOf('')] = v;
return r;
}, {}));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const aux = (names) => {
const hash = {};
let max = 0;
names.forEach(ele => {
if (!hash[ele[1]]) hash[ele[1]] = [];
hash[ele[1]].push(ele[0]);
max = Math.max(hash[ele[1]].length, max);
});
return Object.keys(hash).map(ele => [[...hash[ele], ...Array(max -hash[ele].length).fill("")], ele]);
}
var names = [
['aaa','pin/test1.html'],
['bbb','pin/test2.html'],
['ttt','test.html'],
['ggg','test.html'],
['yyy','un/777.html'],
['ggg','test3.html'],
['nnn','test3.html'],
['eee','n/777.html'],
['sss','pin/test1.html'],
['xxx','pin/test2.html'],
['ppp','pin/test1.html'],
];
console.log(aux(names))
This might help
You do not need jQuery for dealing with regular JS structure, you can achieve what you want with a simple code like this:
var names = [['aaa','pin/test1.html'],['bbb','pin/test2.html'],['ttt','test.html'],['ggg','test.html'],['yyy','un/777.html'],['ggg','test3.html'],['nnn','test3.html'],['eee','n/777.html'],['sss','pin/test1.html'],['xxx','pin/test2.html'],['ppp','pin/test1.html'],];
let lengthToFill = 0;
// collecting all the duplicates into a map
const pathMap = {};
names.forEach(name => {
// just in case if you're not familiar with array destructuring
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
const [pathName, path] = name;
// make sure we have an array to deal with
// just in case you're not familiar with Nullish coalescing operator (??)
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
pathMap[path] = pathMap[path] ?? [];
pathMap[path].push(pathName);
// tracking the max number of elements we're adding into a single entry
lengthToFill = Math.max(lengthToFill, pathMap[path].length);
});
const result = Object.entries(pathMap).map(entry => {
// constructing new array entry based on the data we've collected so far
return [
entry[1].concat(Array(lengthToFill - entry[1].length).fill('')),
entry[0],
];
});
console.log(result);
This solution will work for any number of elements that you'd like to fill the array with ''. It makes sure that the length of final listing is the same for all entries.

How to loop through array.reduce variable

I have a following array, which contains dates.
var arrs= ["2016/10/4", "2016/10/4", "2016/10/7", "2016/10/7", "2016/10/7"];
I am reducing this array to get count of same dates, so I am using following code,
var maps = arrs.reduce(function(prev, cur) {
prev[cur] = (prev[cur] || 0) + 1;
return prev;
}, {});
console.log(maps);
Now, the count is available for each unique dates as follows in browser console,
Object {2016/10/4: 2, 2016/10/7: 3}
I want to make json object for this reduce object.
[{
date : 2016/10/4,
value : 2
},
{
date : 2016/10/7,
value : 3
}]
How to get it, I am not able to get length or make forEach to maps.
After generating the object use Object.keys and Array#map methods to generate the required array.
var arrs = ["2016/10/4", "2016/10/4", "2016/10/7", "2016/10/7", "2016/10/7"];
var maps = arrs.reduce(function(prev, cur) {
prev[cur] = (prev[cur] || 0) + 1;
return prev;
}, {});
maps = Object.keys(maps) // get all property name
// iterate and generate eleemnt
.map(function(k) {
// generate prefered structure of array eleement
return {
date: k,
value: maps[k]
};
});
console.log(maps);

Is array both associative and indexed?

Can an array in JavaScript be associative AND indexed?
I'd like to be able to lookup an item in the array by its position or a key value.
There are no such things as associative arrays in Javascript. You can use object literals, which look like associative arrays, but they have unordered properties. Regular Javascript arrays are based on integer indexes, and can't be associative.
For example, with this object:
var params = {
foo: 1,
bar: 0,
other: 2
};
You can access properties from the object, for example:
params["foo"];
And you can also iterate over the object using the for...in statement:
for(var v in params) {
//v is equal to the currently iterated property
}
However, there is no strict rule on the order of property iteration - two iterations of your object literal could return the properties in different orders.
After reading the Wikipedia definition of associative array, I'm going to break with traditional JavaScript lore and say, "yes, JavaScript does have associative arrays." With JavaScript arrays, you can add, reassign, remove, and lookup values by their keys (and the keys can be quoted strings), which is what Wikipedia says associative arrays should be able to do.
However, you seem to be asking something different--whether you can look up the same value by either index or key. That's not a requirement of associative arrays (see the Wikipedia article.) Associative arrays don't have to give you the ability to get a value by index.
JavaScript arrays are very closely akin to JavaScript objects.
arr=[];
arr[0]="zero";
arr[1]="one";
arr[2]="two";
arr["fancy"]="what?";
Yes, that's an array, and yes, you can get away with non-numeric indices. (If you're curious, after all this, arr.length is 3.)
In most cases, I think you should stick to numeric indices when you use arrays. That what most programmers expect, I think.
The link is to my blog post about the subject.
Native JS objects only accept strings as property names, which is true even for numeric array indices; arrays differ from vanilla objects only insofar as most JS implementations will store numerically indexed properties differently (ie in an actual array as long as they are dense) and setting them will trigger additional operations (eg adjustment of the length property).
If you're looking for a map which accepts arbitrary keys, you'll have to use a non-native implementation. The script is intended for fast iteration and not random-access by numeric indices, so it might nor be what you're looking for.
A barebones implementation of a map which would do what you're asking for could look like this:
function Map() {
this.length = 0;
this.store = {};
}
Map.prototype.get = function(key) {
return this.store.hasOwnProperty(key) ?
this.store[key] : undefined;
};
Map.prototype.put = function(key, value, index) {
if(arguments.length < 3) {
if(this.store.hasOwnProperty(key)) {
this.store[key].value = value;
return this;
}
index = this.length;
}
else if(index >>> 0 !== index || index >= 0xffffffff)
throw new Error('illegal index argument');
if(index >= this.length)
this.length = index + 1;
this[index] = this.store[key] =
{ index : index, key : key, value : value };
return this;
};
The index argument of put() is optional.
You can access the values in a map map either by key or index via
map.get('key').value
map[2].value
var myArray = Array();
myArray["first"] = "Object1";
myArray["second"] = "Object2";
myArray["third"] = "Object3";
Object.keys(myArray); // returns ["first", "second", "third"]
Object.keys(myArray).length; // returns 3
if you want the first element then you can use it like so:
myArray[Object.keys(myArray)[0]]; // returns "Object1"
The order in which objects appear in an associative javascript array is not defined, and will differ across different implementations. For that reason you can't really count on a given associative key to always be at the same index.
EDIT:
as Perspx points out, there aren't really true associative arrays in javascript. The statement foo["bar"] is just syntactic sugar for foo.bar
If you trust the browser to maintain the order of elements in an object, you could write a function
function valueForIndex(obj, index) {
var i = 0;
for (var key in obj) {
if (i++ == index)
return obj[key];
}
}
var stuff = [];
stuff[0] = "foo";
stuff.bar = stuff[0]; // stuff.bar can be stuff["bar"] if you prefer
var key = "bar";
alert(stuff[0] + ", " + stuff[key]); // shows "foo, foo"
I came here to wanting to know if this is bad practice or not, and instead found a lot of people appearing not to understand the question.
I wanted to have a data structure that was ordered but could be indexed by key, so that it wouldn't require iteration for every lookup.
In practical terms this is quite simple, but I still haven't read anything on whether it's a terrible practice or not.
var roygbiv = [];
var colour = { key : "red", hex : "#FF0000" };
roygbiv.push(colour);
roygbiv[colour.key] = colour;
...
console.log("Hex colours of the rainbow in order:");
for (var i = 0; i < roygbiv.length; i++) {
console.log(roygbiv[i].key + " is " + roygbiv[i].hex);
}
// input = "red";
console.log("Hex code of input colour:");
console.log(roygbiv[input].hex);
The important thing is to never change the value of array[index] or array[key] directly once the object is set up or the values will no longer match. If the array contains objects you can change the properties of those objects and you will be able to access the changed properties by either method.
Although I agree with the answers given you can actually accomplish what you are saying with getters and setters. For example:
var a = [1];
//This makes a["blah"] refer to a[0]
a.__defineGetter__("blah", function(){return this[0]});
//This makes a["blah"] = 5 actually store 5 into a[0]
a.__defineSetter__("blah", function(val){ this[0] = val});
alert(a["blah"]); // emits 1
a["blah"] = 5;
alert(a[0]); // emits 5
Is this what you are looking for? i think theres a different more modern way to do getters and setters but cant remember.
The tide has changed on this one. Now you can do that... and MORE! Using Harmony Proxies you could definitely solve this problem in many ways.
You'll have to verify that your targeted environments support this with maybe a little help from the harmony-reflect shim.
There's a really good example on the Mozilla Developer Network on using a Proxy to find an array item object by it's property which pretty much sums it up.
Here's my version:
var players = new Proxy(
[{
name: 'monkey',
score: 50
}, {
name: 'giraffe',
score: 100
}, {
name: 'pelican',
score: 150
}], {
get: function(obj, prop) {
if (prop in obj) {
// default behavior
return obj[prop];
}
if (typeof prop == 'string') {
if (prop == 'rank') {
return obj.sort(function(a, b) {
return a.score > b.score ? -1 : 1;
});
}
if (prop == 'revrank') {
return obj.sort(function(a, b) {
return a.score < b.score ? -1 : 1;
});
}
var winner;
var score = 0;
for (var i = 0; i < obj.length; i++) {
var player = obj[i];
if (player.name == prop) {
return player;
} else if (player.score > score) {
score = player.score;
winner = player;
}
}
if (prop == 'winner') {
return winner;
}
return;
}
}
});
console.log(players[0]); // { name: 'monkey', score: 50 }
console.log(players['monkey']); // { name: 'monkey', score: 50 }
console.log(players['zebra']); // undefined
console.log(players.rank); // [ { name: 'pelican', score: 150 },{ name: 'giraffe', score: 100 }, { name: 'monkey', score: 50 } ]
console.log(players.revrank); // [ { name: 'monkey', score: 50 },{ name: 'giraffe', score: 100 },{ name: 'pelican', score: 150 } ]
console.log(players.winner); // { name: 'pelican', score: 150 }
The latest MDN documentation makes it quiet clear that Array index must be integers.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
let arr=[];
arr[0]="zero";
arr[1]="one";
arr[2]="two";
arr["fancy"]="what?";
//Arrays cannot use strings as element indexes (as in an associative array) but must use integers.
//Setting non-integers using bracket notation will not set an element to the Array List itself
//A non-integer will set a variable associated with that ARRAY Object property collection
let denseKeys = [...arr.keys()];
console.log(denseKeys);//[ 0, 1, 2 ]
console.log("ARRAY Keys:"+denseKeys.length);//3
let sparseKeys = Object.keys(arr);
console.log(sparseKeys);//[ '0', '1', '2', 'fancy' ]
console.log("Object Keys:"+sparseKeys.length);//4
const iterator = arr.keys();
for (const key of iterator) {
console.log(key);//0,1,2
}
Yes.
test = new Array();
test[0] = 'yellow';
test['banana'] = 0;
alert(test[test['banana']]);

Categories