ESLint doesn't allow for in - javascript

I have an object
currentValues= {hey:1212, git:1212, nmo:12121}
and I use for in like this:
for (const key in currentValues) {
if (Object.prototype.hasOwnProperty.call(currentValues, key)) {
yield put(setCurrentValue(key, currentValues[key]));
}
}
ESLint shows me an error which is saying:
ESLint: for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array. (no-restricted-syntax
How should I edit my code?

It says,
Use Object.{keys,values,entries}, and iterate over the resulting
array.
So you could do something like this to get the object keys as an array and then loop through the keys to make necessary changes.
currentValues= {hey:1212, git:1212, nmo:12121}
Object.keys(currentValues).forEach(function(key) {
yield put(setCurrentValue(key, currentValues[key]));
})

I used the following:
const keys = Object.keys(currentValues);
const values = Object.values(currentValues);
for (let i = 0; i < keys.length; i += 1) {
yield put(setCurrentValue(keys[i], values[i]));
}
This is correct and without ESLint errors.

You can get the array of all your values inside your object just doing
var myValuesInArray = Object.values(currentValues);

I would do it by refactoring, in the following ways.
const currentValues = { hey: 1212, git: 1212, nmo: 12121 };
Object.keys(currentValues).forEach((e) => console.log(`${e} : ${currentValues[e]}`));
Results:
hey : 1212
git : 1212
nmo : 12121
Object.values(currentValues).forEach((e) => console.log(`Values: ${e}`));
Results:
(2)Values: 1212
Values: 12121
Object.entries(currentValues).forEach((e) => console.log(`${e[0]} : ${e[1]}`));
Results:
hey : 1212
git : 1212
nmo : 12121

let animal = {
eats: "Eating",
};
let rabbit = {
jumps: "Jumping",
};
rabbit.__proto__ = animal;
for (const rabbitProps in rabbit) {
// This will print both eats and jumps properties because they're part of
// prototype chain
console.log("rabbitProps: ", rabbitProps);
}
// This prints only jumps as Object.keys shows only the keys of object
console.log(Object.keys(rabbit));
Checking out the above code you can see that when using for...in loop[ it will show all the properties that are part of object as well as properties set in the prototype chain of the object and so eslint suggests to use Object.keys or value or entries, as they do not look into prototype chain instead they just look at your object.

I know it is similar to the above, but here is a full example:
const data = res.data;
const keys = Object.keys(data);
const values = Object.values(data);
for (let i = 0; i <= keys.length; i += 1) {
if (Object.prototype.hasOwnProperty.call(values, i)) {
this.rows.push({
name: values[i].name,
email: values[i].email,
address: values[i].address,
phone: values[i].phone,
role: values[i].role,
});
}
}

try this instead:
Object.keys(currentValues).map(key => (yield put(setCurrentValue(key, currentValues[key]))));

Using for...in will iterate over all properties including those from Object prototype. I am not sure why you are doing Object.prototype.hasOwnProperty.call(currentValues, key)
instead of just:
currentValues.hasOwnProperty(key).
I think this should make ESLint aware that you are filtering for own properties only.
However, I suggest using for (const key of Object.keys()), which is more semantic.

Related

implement a list with a static method javascript

I must reimplement a list and the method forEach with the following instructions:
// Do not construct any array literal ([]) in your solution.
// Do not construct any arrays through new Array in your solution.
// DO not use any of the Array.prototype methods in your solution.
// You may use the destructuring and spreading (...) syntax from Iterable.
the result should look like:
const list = List.create(1, 2)
list.forEach((item) => console.log(item))
Here is my incomplete solution:
export class List {
constuctor(){
}
public static create(...values: number[]): List {
// Do *not* construct any array literal ([]) in your solution.
// Do *not* construct any arrays through new Array in your solution.
// DO *not* use any of the Array.prototype methods in your solution.
// You may use the destructuring and spreading (...) syntax from Iterable.
List list = new List();
values.forEach(function(item){
list.push(item);
});
return list;
}
public forEach(callback: any){
for (let i = 0; i<this.length ; i++){
callback(this[i], i, this);
}
}
}
in the create loop, but the problem, as a static method, the this is not recognized
EDITED thanks to comments
...this is not recognised
It is. But you have not given this any property. And this is because:
constuctor should be written as constructor
You need to define a push method (since you call it in create)
You need to define a length property (since you reference it in forEach)
Furthermore, there some other issues:
you write that Array.prototype functions cannot be used, but your code has values.forEach(), ... so that is a violation of that rule. Use a for..of loop instead.
Here is your code with those remarks taken on board:
class List {
constructor() {
this.length = 0;
}
push(value) {
this[this.length++] = value;
}
static create(...values) {
let list = new List();
for (let item of values) {
list.push(item);
}
return list;
}
forEach(callback) {
for (let i = 0; i < this.length ; i++) {
callback(this[i], i, this);
}
}
}
const list = List.create(1, 2)
list.forEach((item) => console.log(item))
Remarks
The above "test" will be fine, but when also assignments to properties are to work correctly, like list[2] = 3, then there are more things to take care of. Take for instance this program:
const list = List.create(1, 2);
list[5] = 42; // should update length
list.check = true; // should not update length
console.log("length = " + list.length);
console.log("enumerable keys are " + Object.keys(list));
list.forEach((item) => console.log(item)); // should not output empty slots
list.length = 1; // should delete some index properties
list.forEach((item) => console.log(item)); // should not output deleted items
...then the output should be:
length = 6
enumerable keys are 0,1,5,check
1
2
42
1
You can make this happen by trapping the access to properties, and making length a getter/setter. But you'd also need to distinguish between properties that are array indices, and which are not, so all-in-all that would make the code less trivial.

Inserting Elements In Array As an Object but without using keys in Javascript

Current Situation :
[{
"Severity":1,
"Name":"Yash"
}, {
"Severity":2,
"Name":"Yashaswi"
}]
Desired Situation :
[{1: "Yash"}, {2: "Yashaswi"}]
Code being used :
widTags = ["Severity","Name"];
let tempobj = {};
for(let key in widTags) {
tempobj[key]=prop;
}
dataArrayWid.push(tempobj)
This solution does what you're suggesting without changing the syntax too much from your original code:
const original = [
{"Severity":1, "Name":"Yash"},
{"Severity":2, "Name":"Yashaswi"}
];
const final = [];
for (const oldObj of original){ // (Prefer `for...of` to iterate Arrays)
const
newObj = {},
key = oldObj["Severity"],
val = oldObj["Name"];
newObj[key] = val; // Uses Severity val as prop name & Name val as prop val
final.push(newObj);
}
console.log(final);
And this is a more concise version:
const
original = [ {"Severity":1, "Name":"Yash"}, {"Severity":2, "Name":"Yashaswi"} ],
final = original.map(obj => ( { [obj.Severity]: obj.Name } ));
console.log(final);
(Here, the .map method of Arrays makes a new Array with each element modified by a function -- in this case an Arrow function).
Note:
The extra parentheses tell JavaScript that their contents are an expression containing our Object literal to be returned, not a block of code statements.
Similarly, the extra brackets in the Object literal tell JavaScript that their contents are an expression specifying a computed property name, not a static property name,
You can achieve that by using Array.map() method.
Demo :
const dataArrayWid = [{
"Severity":1,
"Name":"Yash"
}, {
"Severity":2,
"Name":"Yashaswi"
}];
const result = dataArrayWid.map((obj) => {
return {
[obj.Severity]: obj.Name
}
});
console.log(result);

How to form an array using values present against all the that exists in a json object? [duplicate]

If there is a JavaScript object:
var objects={...};
Suppose, it has more than 50 properties, without knowing the property names (that's without knowing the 'keys') how to get each property value in a loop?
Depending on which browsers you have to support, this can be done in a number of ways. The overwhelming majority of browsers in the wild support ECMAScript 5 (ES5), but be warned that many of the examples below use Object.keys, which is not available in IE < 9. See the compatibility table.
ECMAScript 3+
If you have to support older versions of IE, then this is the option for you:
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var val = obj[key];
// use val
}
}
The nested if makes sure that you don't enumerate over properties in the prototype chain of the object (which is the behaviour you almost certainly want). You must use
Object.prototype.hasOwnProperty.call(obj, key) // ok
rather than
obj.hasOwnProperty(key) // bad
because ECMAScript 5+ allows you to create prototypeless objects with Object.create(null), and these objects will not have the hasOwnProperty method. Naughty code might also produce objects which override the hasOwnProperty method.
ECMAScript 5+
You can use these methods in any browser that supports ECMAScript 5 and above. These get values from an object and avoid enumerating over the prototype chain. Where obj is your object:
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]];
// use val
}
If you want something a little more compact or you want to be careful with functions in loops, then Array.prototype.forEach is your friend:
Object.keys(obj).forEach(function (key) {
var val = obj[key];
// use val
});
The next method builds an array containing the values of an object. This is convenient for looping over.
var vals = Object.keys(obj).map(function (key) {
return obj[key];
});
// use vals array
If you want to make those using Object.keys safe against null (as for-in is), then you can do Object.keys(obj || {})....
Object.keys returns enumerable properties. For iterating over simple objects, this is usually sufficient. If you have something with non-enumerable properties that you need to work with, you may use Object.getOwnPropertyNames in place of Object.keys.
ECMAScript 2015+ (A.K.A. ES6)
Arrays are easier to iterate with ECMAScript 2015. You can use this to your advantage when working with values one-by–one in a loop:
for (const key of Object.keys(obj)) {
const val = obj[key];
// use val
}
Using ECMAScript 2015 fat-arrow functions, mapping the object to an array of values becomes a one-liner:
const vals = Object.keys(obj).map(key => obj[key]);
// use vals array
ECMAScript 2015 introduces Symbol, instances of which may be used as property names. To get the symbols of an object to enumerate over, use Object.getOwnPropertySymbols (this function is why Symbol can't be used to make private properties). The new Reflect API from ECMAScript 2015 provides Reflect.ownKeys, which returns a list of property names (including non-enumerable ones) and symbols.
Array comprehensions (do not attempt to use)
Array comprehensions were removed from ECMAScript 6 before publication. Prior to their removal, a solution would have looked like:
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
ECMAScript 2017+
ECMAScript 2016 adds features which do not impact this subject. The ECMAScript 2017 specification adds Object.values and Object.entries. Both return arrays (which will be surprising to some given the analogy with Array.entries). Object.values can be used as is or with a for-of loop.
const values = Object.values(obj);
// use values array or:
for (const val of Object.values(obj)) {
// use val
}
If you want to use both the key and the value, then Object.entries is for you. It produces an array filled with [key, value] pairs. You can use this as is, or (note also the ECMAScript 2015 destructuring assignment) in a for-of loop:
for (const [key, val] of Object.entries(obj)) {
// use key and val
}
Object.values shim
Finally, as noted in the comments and by teh_senaus in another answer, it may be worth using one of these as a shim. Don't worry, the following does not change the prototype, it just adds a method to Object (which is much less dangerous). Using fat-arrow functions, this can be done in one line too:
Object.values = obj => Object.keys(obj).map(key => obj[key]);
which you can now use like
// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
If you want to avoid shimming when a native Object.values exists, then you can do:
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Finally...
Be aware of the browsers/versions you need to support. The above are correct where the methods or language features are implemented. For example, support for ECMAScript 2015 was switched off by default in V8 until recently, which powered browsers such as Chrome. Features from ECMAScript 2015 should be be avoided until the browsers you intend to support implement the features that you need. If you use babel to compile your code to ECMAScript 5, then you have access to all the features in this answer.
By using a simple for..in loop:
for(var key in objects) {
var value = objects[key];
}
Here's a reusable function for getting the values into an array. It takes prototypes into account too.
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
If you have access to Underscore.js, you can use the _.values function like this:
_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
ES5 Object.keys
var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
If you really want an array of Values, I find this cleaner than building an array with a for ... in loop.
ECMA 5.1+
function values(o) { return Object.keys(o).map(function(k){return o[k]}) }
It's worth noting that in most cases you don't really need an array of values, it will be faster to do this:
for(var k in o) something(o[k]);
This iterates over the keys of the Object o. In each iteration k is set to a key of o.
const myObj = { a:1, b:2, c:3 }
Get all values:
the shortest way:
const myValues = Object.values(myObj)
const myValues = Object.keys(myObj).map(key => myObj[key])
You can loop through the keys:
foo = {one:1, two:2, three:3};
for (key in foo){
console.log("foo["+ key +"]="+ foo[key]);
}
will output:
foo[one]=1
foo[two]=2
foo[three]=3
ECMA2017 onwards:
Object.values(obj) will fetch you all the property values as an array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
The question doesn't specify whether wanting inherited and non-enumerable properties also.
There is a question for getting everything, inherited properties and non-enumerable properties also, that Google cannot easily find.
If we are to get all inherited and non-enumerable properties, my solution for that is:
function getAllPropertyNames(obj) {
let result = new Set();
while (obj) {
Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
And then iterate over them, just use a for-of loop:
function getAllPropertyNames(obj) {
let result = new Set();
while (obj) {
Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
let obj = {
abc: 123,
xyz: 1.234,
foobar: "hello"
};
for (p of getAllPropertyNames(obj)) console.log(p);
For those early adapting people on the CofeeScript era, here's another equivalent for it.
val for key,val of objects
Which may be better than this because the objects can be reduced to be typed again and decreased readability.
objects[key] for key of objects
Apparently - as I recently learned - this is the fastest way to do it:
var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
// do whatever in here
var obj = objs[objKeys[i]];
}
use a polyfill like:
if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}
then use
Object.values(my_object)
3) profit!
const object1 = {
a: 'somestring',
b: 42
};
for (let [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}
// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed
I realize I'm a little late but here's a shim for the new firefox 47 Object.values method
Object.prototype.values = Object.prototype.values || function(obj) {
return this.keys(obj).map(function(key){
return obj[key];
});
};
Object.entries do it in better way.
var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
Object.entries(dataObject).map(itemArray => {
console.log("key=", itemArray[0], "value=", itemArray[1])
})
Use: Object.values(), we pass in an object as an argument and receive an array of the values as a return value.
This returns an array of a given object own enumerable property values. You will get the same values as by using the for in loop but without the properties on the Prototype. This example will probably make things clearer:
function person (name) {
this.name = name;
}
person.prototype.age = 5;
let dude = new person('dude');
for(let prop in dude) {
console.log(dude[prop]); // for in still shows age because this is on the prototype
} // we can use hasOwnProperty but this is not very elegant
// ES6 +
console.log(Object.values(dude));
// very concise and we don't show props on prototype
Here's a function similar to PHP's array_values()
function array_values(input) {
var output = [], key = '';
for ( key in input ) { output[output.length] = input[key]; }
return output;
}
Here's how to get the object's values if you're using ES6 or higher:
Array.from(values(obj));
Compatible with ES7 even some browsers do not support it yet
Since , Object.values(<object>) will be built-in in ES7 &
Until waiting all browsers to support it , you could wrap it inside a function :
Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])
Then :
Object.vals({lastname:'T',firstname:'A'})
// ['T','A']
Once browsers become compatible with ES7, you will not have to change anything in your code.
we can fetch data using three methods below
Use map function
data.map( item => { console.log(item) }
Use for loop
for( let i = 0; i < data.length; i++){
console.log(item);
}
Use for in loop
for(key in data) {
if(data.hasOwnProperty(key)) {
const value = data[key];
console.log(value);
}
}
I think the easiest option is like this:
Object.keys(data).forEach(function (key, index) {
var value = data[key];
console.log(key, index, value);
});
For example, a runnable code is added here:
const user = {
name: 'Alex',
age: 30,
};
Object.keys(user).forEach(function (key, index) {
var value = user[key];
console.log(key, index, value);
});
var objects={...}; this.getAllvalues = function () {
var vls = [];
for (var key in objects) {
vls.push(objects[key]);
}
return vls;
}
in ECMAScript5 use
keys = Object.keys(object);
Otherwise if you're browser does not support it, use the well-known for..in loop
for (key in object) {
// your code here
}
Now I use Dojo Toolkit because older browsers do not support Object.values.
require(['dojox/lang/functional/object'], function(Object) {
var obj = { key1: '1', key2: '2', key3: '3' };
var values = Object.values(obj);
console.log(values);
});
Output :
['1', '2', '3']
use
console.log(variable)
and if you using google chrome open Console by using Ctrl+Shift+j
Goto >> Console

How to get the name from the array in javascript?

I am fairly new to JavaScript and I am trying to extract the name Sam from the array. The output that I'm getting is name. How do I get Sam? Thank you in advance. I apologize but I know this is a fairly novice question.
I am trying to loop by using forEach.
let Person = {
name: ['Sam']
}
let handler = Object.keys(Person)
handler.forEach(function(element){
console.log(element)
})
Object.keys() only gives you keys
Use Object.entries() if you want key and value
Use Object.values() if you only want values
let Person = {
name: ['Sam']
}
for (const fn of ["values", "keys", "entries"]) {
console.log(`Using: Object.${fn}()`);
for (const v of Object[fn](Person)) {
console.log(v);
}
}
Instead of Object.keys use Object.values
If you know in advance that your name array is located under the key name, then access it directly
const person = { name: ['Sam'] };
console.log(person.name);
console.log(person.name[0]);
Otherwise, use Object.values() to enumerate the values in the object, but you might get more values than simply the names array and you will have to find out which value contains the names you are looking for:
const person = { name: ['Sam'], anotherProp: 'hello' };
console.log(Object.values(person));
Using Object.entries() is not helpful in this situation as if you use it, it means that you know under which property is located your name array, and if this is the case, simply access the array directly.
let Person = {
name: ['Sam',"Bob","Alice"]
}
let count = Person.name.length;
for(let i = 0; i<count; i++){
console.log( Person.name[i])
}
If you use Object.keys() you can get the value by using object[key] bracket notation or object.key dot notation.
Object.keys(obj).forEach(key => obj[key]);
let Person = {
name: ['Sam']
}
Object.keys(Person).forEach(name => console.log(`${name} = ${Person[name]}`));

How to do multiple let in for loop

Can I assign 2 let in for loop? I tried this but gives me warning k[ts] ')' expected.:
for(let key in app.date let key2 in app.date2) {
data_series.push({
"year": app.date[key]._id,
"italy": app.date[key].count,
"germany": app.date2[key2].count2,
});
}
What is the correct syntax?
Assuming that both objects have the same number of keys, in order to iterate over both at once, you'd have to first construct an object of some sort that contains key pairs. But, from your code, it looks like you're interested only in the value at that key, not the key itself - if what you want is clear, short code, you might use an array method instead: iterate over the Object.values of app.date, and use the index to access the appropriate value inside date2:
const date2Values = Object.values(app.date2);
Object.values(app.date).forEach(({ _id, count }, i) => {
data_series.push({
year: _id,
italy: count,
germany: date2Values[i].count2
});
});
If you had to use for, then construct an object of key pairs beforehand, and iterate with for..of:
const date2Keys = Object.keys(app.date2);
const allKeys = Object.keys(app.date)
.map((key, i) => ({ key, key2: date2Keys[i] }));
for (const { key, key2 } of allKeys) {
// etc
}
or, it might be clearer with a plain for loop instead:
const dateKeys = Object.keys(app.date);
const date2Keys = Object.keys(app.date2);
for (let i = 0, { length } + Object.keys(app.date); i < length; i++) {
const key = dateKeys[i];
const key2 = date2Keys[i];
// etc
}
But the Object.values version is probably preferable, since it's more abstract, functional, and doesn't require manual iteration.
Also, if data_series is an empty array beforehand, it would be more appropriate to use .map than to use forEach and push:
const date2Values = Object.values(app.date2);
const data_series = Object.values(app.date).map(({ _id, count }, i) => ({
year: _id,
italy: count,
germany: date2Values[i].count2
});
If at all possible, I'd recommend changing your data structure so that each item of date and date2 is clearly associated with the other, such as an array, rather than depending on each object happening to have the same ordered property names. Although property order is guaranteed in modern browsers, it's not a good thing for code to depend on.

Categories