Using Slickgrid I am trying to set the CSS of a cell using setCellCssStyles method
for (var rowIndx = 1; rowIndx < movmentRows.length; rowIndx++) {
grid.setCellCssStyles("disabled", {
rowIndx: {
san: "slick-cellreadonly",
ean: "slick-cellreadonly",
},
});
}
I understand its because I am using a variable for a key in the for loop.
But I don't understand how to make this work.
I tried to replace rowIndx with [rowIndx] but I am getting syntax error, so I think my JavaScript is not ES6. Then I tried the following but this is also giving syntax error with -
Encountered '['and Expected keyword or brace.
for(var rowIndx=1;rowIndx<movmentRows.length;rowIndx++){
var key = {};
grid.setCellCssStyles("natCol-greyed", {
key[rowIndx] : {
sourceAccountNational: "slick-cellreadonly",
excludeAccountNational: "slick-cellreadonly"
}
});
}
Please suggest.
If you are trying to create an object but want to use a variable for the key, the syntax is as follows:
let keyName = "foo"
let object = { [keyName]: "bar" }
// gives the object `{"foo": "bar}
in older javascript you have to assign to a key after the object is created:
let keyName = "foo"
let object = {}
object[keyName] = "bar"
Also, I try to never do a "manual" loop when I can use an iterator. It's less error prone than a "manual" loop, and allows you to use different types of collections other than just arrays, so it's more flexible. there are two main ways to do this:
A for … of loop:
let collection = ["a", "b", "c"]
for (let value of collection) {
console.log("value:", value)
}
// if you also want the index
for (let [index, value] of collection.entries()) {
console.log("value and index:", value, index)
}
// or _just_ the indexes (note this skip empty values in sparse arrays)
for (let index of collection.keys()) {
console.log("index:", index)
}
Using forEach:
collection.forEach((item, index) => console.log(item, index))
Both these methods usually work about the same, but the for … of loop is closer to a "manual" loop. However, forEach is a bit older, so may be available more places. Also, take a look at the similar map.
If movementRows is an array you can use a for...of loop like so:
for (const [index, row] of movmentRows.entries()) { //index is the index of each itteration and row is the value
grid.setCellCssStyles("disabled", {
[row]: {
san: "slick-cellreadonly",
ean: "slick-cellreadonly",
},
});
}
To set an object key as a variable you can put it in brackets..
Note on for..of loop: It is not supported in IE.
More on how to dynamically set object properties
More on For...Of loop
Related
I just want to add objects inside objects dynamically using array technique. I know how do we add Objects - those are Object[key] or Object.key but suppose I thing I have to add multiple objects dymanically using function
Note: below example is just for demonstration
let array = ['first','second','third']
let object = {}
function addObject(key) {
object[key] = "someValue"
}
for (var i = 0; i < array.length; i++) {
addObject(array[i])
}
This gives output like this { first: 'someValue', second: 'someValue', third: 'someValue'}. Actually I want my output something like nested object {first:{second:{third:'somevalue'}}} not exactly this but a nested object first > second > third.
My Actual question is like how to add objects inside object in this situation. What is the correct syntax for this. Like object[first][second][third] is standard way to achieve but I can't add + operator in the left side or calling array(['first.second.third'])
`
function addObject(key) {
object[key] + [key] = "someValue"
}
or calling
array(['first.second.third'])
I'd use reduceRight to iterate over the array starting from the end. Pass in the final property value as the initial accumulator, so you get { third: 'someValue' } on the first iteration, and return it so it's the new accumulator. On subsequent iterations, do the same thing - create another object enclosing the last returned accumulator.
const array = ['first','second','third']
const nestedValue = 'someValue';
const result = array.reduceRight(
(a, prop) => ({ [prop]: a }),
nestedValue
);
console.log(result);
How do I get the previous element of an ES6 loop.
For example, if I have my for loop written like this:
for (let item of data){
console.log(item.name)
}
I also want to get the name of the previous item of the loop:
I tried:
data[item-1].name
which does not work.
When I used ES5 array
for(let i =0;i<details.length;i++){
console.log(details[i-1].PartNumber)
}
gave me the previous element of the loop. I am not sure how I can do this usinf the new syntax
You can save a reference to previous object into a separate variable.
let data = [{name: 'name1'}, {name: 'name2'}, {name: 'name3'}, {name: 'name4'}, {name: 'name5'}];
let prev;
for (let item of data){
console.log({current: item.name, previous: prev && prev.name})
prev = item;
}
Another solution would be to define a generator function that iterates over pairs of values where each pairing has the previous and current values of that iteration. Doing this would allow you to iterate using the for .. of flow control in a reasonably clean and clear way.
A simple way to do that would be as follows:
const data = [1,2,3,4];
/* Define generator function which returns
a pair of previous/current values from input
iteratable, per iteration */
function *iteratePairs(iteratable) {
let prev;
for(const item of iteratable) {
// Return the pair for this iteration
yield [prev, item]
// Update the previous item
prev = item;
}
}
// Invoke the iteratePairs generator using for..of
// flow control
for (let pair of iteratePairs(data)){
console.log(pair)
}
Hope that helps!
If you want to use for..of and access the previous index, call .entries() on the array first, so you get both the key and the value, and then you can use bracket notation to look up the i - 1 property:
for (const [i, value] of data.entries()){
if (i >= 1) {
console.log(data[i - 1].PartNumber);
}
}
const data = [
{ PartNumber: 0 },
{ PartNumber: 1 },
{ PartNumber: 2 },
]
for (const [i, value] of data.entries()){
if (i >= 1) {
console.log(data[i - 1].PartNumber);
}
}
You don't. Thats kind of the point. The ES6 for-of loop abstracts the concept of the index away, and should be used if you want a simple loop. If you want to manually access elements based on the index there is nothing wrong with using a simple for loop.
However what you could do is this:
for(let [idx, elem] of Object.entries(arr)) {
console.log(arr[idx -1]);
}
But I would recommend to use a simple for loop.
My code:
rbx.getPlayers(539310, 1).promise.then(players => {
console.log(players)
for (var list in players.players) {
console.log(list)
var key = Object.Key(list)
console.log(Key)
}
})
What it outputs:
{ total: 9,
players:
{ AgentJay400: 65910635,
MatthewHAndreas: 49787909,
coolguysocoolroblox: 165524669,
CAMPER5155: 45422370,
Mavnkei: 69082588,
kaankerem123: 92305180,
egehan432: 120777218,
panpanaber54: 31962303,
IXTactical_CactusXI: 17451343 } }
AgentJay400
MatthewHAndreas
coolguysocoolroblox
CAMPER5155
Mavnkei
kaankerem123
egehan432
panpanaber54
IXTactical_CactusXI
Problem:
I need the number values of each user (So {AgentJay4000: 65910635} I would want the 65910635) Node.js does not seem to have Object.keys so... I have no clue how to get the number...
Node should definitely have Object.keys. If your version doesn't you should update node. When you call Object.keys you get an array in return, so you can do awesome array things like map, reduce, forEach:
Object.keys(players.players).forEach(function(key) {
console.log(key, players.players[key])
})
If you just want the number values, then map it:
Object.keys(players.players).map(function(key) {
return players.players[key]
})
Now you have an array of the numbers only.
Try like this.You can access your object value using . operator.
Suppose you have an object:
var obj={
key1:value1,
key2:value2
}
Then access values like obj.key1 or obj['key1'].
to get all the values.Use Object.values(obj);
var obj = { total: 9,
players:
{ AgentJay400: 65910635,
MatthewHAndreas: 49787909,
coolguysocoolroblox: 165524669,
CAMPER5155: 45422370,
Mavnkei: 69082588,
kaankerem123: 92305180,
egehan432: 120777218,
panpanaber54: 31962303,
IXTactical_CactusXI: 17451343 } };
var players = obj.players;
var number_values = Object.values(players);
console.log(number_values );
You can output the keys and their associated numbers by doing the following:
rbx.getPlayers(539310, 1).promise.then(players => {
console.log(players)
for (var key in players.players) {
console.log(key, ':', players.players[key])
}
})
To demonstrate how Object.keys works an alternative method of accessing the players - this does the same as the above.
rbx.getPlayers(539310, 1).promise.then(players => {
var keys = Object.keys(players.players);
for (var i = 0; i < keys.length; i++) {
let key = keys[i];
let player = players.players[key];
console.log(key, ':', players.players[key])
}
});
The mistakes you made in your attempt were you were attempting to access Object.key which was a typo for Object.keys and attempting to obtain a list of keys from a string (as a loop such as for(var key in obj) will set key to each key in obj and all object keys are strings).
Is there any way to create a generic for loop that will loop through either an array or an object correctly? I know I can write the following for loop, but it will also loop through other properties that would be added to an array.
for (item in x) {
console.log(item)
}
By this I mean a for loop that will iterate:
x = [1, 2]
x.foo = "foo"
y = {first:1, second: 2}
x as
1
2
y as
first
second
The reason behind this is that I won't know until runtime what x will be (either an Array or an Object). Is my only option to create a function that will check at runtime?
Use the for..of loop.
Iterating over arrays
const array = [1, 2];
array.foo = "test";
for (const number of array) {
console.log(number); // skips array.foo
}
Iterating over objects
const object = {
some: "string",
number: 42
};
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}
Anyway, from a code-style point of view, you should still check whether your object is an array before you iterate over it. You can use Array.isArray to achieve that. So, assuming data is either an object or an array:
if (Array.isArray(data)) {
for (const element of data) {
// Iterate over array
}
}
else {
for (const [key, value] of Object.entries(data)) {
// Iterate over object
}
}
Generic looping
Since in JavaScript, typeof [] === "object" (i. e. arrays are objects that use the element's index as its key), you could reduce it to a single loop with Object.entries:
for (const [key, value] of Object.entries(data)) {
// For arrays, `key` will be the index
}
Beware though that this latter method will not do justice to your exclusion of dynamic properties (e. g. array.foo), as you'll iterate over the result of Object.entries. If you do need to make this exclusion, use two for..of loops with Array.isArray as shown above.
If it's just the index/key values you need as per your expected output, here's a simple one-liner.
function loop(x) {
return (Array.isArray(x) ? x : Object.keys(x)).forEach(el => console.log(el));
}
loop(x); // 1 2
loop(y); // First Second
DEMO
Why is my for for-each loop not iterating over my JavaScript associative array object?
// Defining an array
var array = [];
// Assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";
// Expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
jQuery each() could be helpful: https://api.jquery.com/jQuery.each/
The .length property only tracks properties with numeric indexes (keys). You're using strings for keys.
You can do this:
var arr_jq_TabContents = {}; // no need for an array
arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;
for (var key in arr_jq_TabContents) {
console.log(arr_jq_TabContents[key]);
}
To be safe, it's a good idea in loops like that to make sure that none of the properties are unexpected results of inheritance:
for (var key in arr_jq_TabContents) {
if (arr_jq_TabContents.hasOwnProperty(key))
console.log(arr_jq_TabContents[key]);
}
edit — it's probably a good idea now to note that the Object.keys() function is available on modern browsers and in Node etc. That function returns the "own" keys of an object, as an array:
Object.keys(arr_jq_TabContents).forEach(function(key, index) {
console.log(this[key]);
}, arr_jq_TabContents);
The callback function passed to .forEach() is called with each key and the key's index in the array returned by Object.keys(). It's also passed the array through which the function is iterating, but that array is not really useful to us; we need the original object. That can be accessed directly by name, but (in my opinion) it's a little nicer to pass it explicitly, which is done by passing a second argument to .forEach() — the original object — which will be bound as this inside the callback. (Just saw that this was noted in a comment below.)
This is very simple approach. The advantage is you can get keys as well:
for (var key in array) {
var value = array[key];
console.log(key, value);
}
For ES6:
array.forEach(value => {
console.log(value)
})
For ES6 (if you want the value, index and the array itself):
array.forEach((value, index, self) => {
console.log(value, index, self)
})
If Node.js or the browser support Object.entries(), it can be used as an alternative to using Object.keys() (Pointy's answer).
const h = {
a: 1,
b: 2
};
Object.entries(h).forEach(([key, value]) => console.log(value));
// logs 1, 2
In this example, forEach uses destructuring assignment of an array.
There are some straightforward examples already, but I notice from how you've worded your question that you probably come from a PHP background, and you're expecting JavaScript to work the same way -- it does not. A PHP array is very different from a JavaScript Array.
In PHP, an associative array can do most of what a numerically-indexed array can (the array_* functions work, you can count() it, etc.). You simply create an array and start assigning to string indexes instead of numeric.
In JavaScript, everything is an object (except for primitives: string, numeric, boolean), and arrays are a certain implementation that lets you have numeric indexes. Anything pushed to an array will affect its length, and can be iterated over using Array methods (map, forEach, reduce, filter, find, etc.) However, because everything is an object, you're always free to simply assign properties, because that's something you do to any object. Square-bracket notation is simply another way to access a property, so in your case:
array['Main'] = 'Main Page';
is actually equivalent to:
array.Main = 'Main Page';
From your description, my guess is that you want an 'associative array', but for JavaScript, this is a simple case of using an object as a hashmap. Also, I know it's an example, but avoid non-meaningful names that only describe the variable type (e.g. array), and name based on what it should contain (e.g. pages). Simple objects don't have many good direct ways to iterate, so often we'll turn then into arrays first using Object methods (Object.keys in this case -- there's also entries and values being added to some browsers right now) which we can loop.
// Assigning values to corresponding keys
const pages = {
Main: 'Main page',
Guide: 'Guide page',
Articles: 'Articles page',
Forum: 'Forum board',
};
Object.keys(pages).forEach((page) => console.log(page));
arr_jq_TabContents[key] sees the array as an 0-index form.
Here is a simple way to use an associative array as a generic Object type:
Object.prototype.forEach = function(cb){
if(this instanceof Array) return this.forEach(cb);
let self = this;
Object.getOwnPropertyNames(this).forEach(
(k)=>{ cb.call(self, self[k], k); }
);
};
Object({a:1,b:2,c:3}).forEach((value, key)=>{
console.log(`key/value pair: ${key}/${value}`);
});
This is (essentially) incorrect in most cases:
var array = [];
array["Main"] = "Main page";
That creates a non-element property on the array with the name Main. Although arrays are objects, normally you don't want to create non-element properties on them.
If you want to index into array by those names, typically you'd use a Map or a plain object, not an array.
With a Map (ES2015+), which I'll call map because I'm creative:
let map = new Map();
map.set("Main", "Main page");
you then iterate it using the iterators from its values, keys, or entries methods, for instance:
for (const value of map.values()) {
// Here, `value` will be `"Main page"`, etc.
}
Using a plain object, which I'll creatively call obj:
let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`
you'd then iterate its contents using Object.keys, Object.values, or Object.entries, for instance:
for (const value of Object.values(proches_X)) {
// Here, `value` will be `"Main page"`, etc.
}
var obj = {
no: ["no", 32],
nt: ["no", 32],
nf: ["no", 32, 90]
};
count = -1; // Which must be a static value
for (i in obj) {
count++;
if (obj.hasOwnProperty(i)) {
console.log(obj[i][count])
};
};
In this code I used the brackets method for call values in an array because it contained an array. However, briefly the idea which a variable i has a key of property and with a loop called both values of the associative array.
It is the perfect method.
You can do this:
var array = [];
// Assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";
array.forEach(value => {
console.log(value)
})
It seems like almost every answer is not what was asked at the very first place.
It's seems bit off that foreach-loop does not work. and simple for-loop will not work as well because length property will be zero in case of associative arrays(one of the fallback). but for-in do the thing for associative array
// Defining an array
var array = [];
// Assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";
// Expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var index in array) {
console.log(index,array[index]);
}