I have a list of objects. Every object has a property which is a list of elements:
{ name : 'Club 01'
, id : 1
, form : 45
, points : 0
, tactics : 'neutral'
, played : 0
, gameset : 0
, playedWith : [ 8, 1, 2, 3 ]
}
I want to go through the list and console log all existing elements:
for (let a = 0; a<clubs.width; a++) {
for (let b = 0; b<clubs[a].playedWith.width; b++) {
console.log(clubs[a].playedWith[b]);
}
}
when i do it for one item, this works. however when i do it with a loop as aboce, this brings me to
undefined
Whats wrong with my code? How do i console log all items within playedWith property?
Elikill58 is right. Arrays have length property, not width property.
So your code would work well this way:
for (let a = 0; a < clubs.length; a++){
for (let b = 0; b < clubs[a].playedWith.length; b++){
console.log(clubs[a].playedWith[b]);
}
}
Also, if you want to iterate through all items in the array, just for the sake of simplicity, you can write it like so:
for (const club of clubs) {
for (const width of club.playedWith) {
console.log(width);
}
}
You have to use length instead of width for both loop.
Here is an example :
var clubs = [
{ name : 'Club 01'
, id : 1
, form : 45
, points : 0
, tactics : 'neutral'
, played : 0
, gameset : 0
, playedWith : [ 8, 1, 2, 3 ]
}
];
for (let a = 0; a < clubs.length; a++) {
for (let b = 0; b < clubs[a].playedWith.length; b++) {
console.log(clubs[a].playedWith[b]);
}
}
let b = {
name: 'Club 01',
id: 1,
form: 45,
points: 0,
tactics: 'neutral',
played: 0,
gameset: 0,
playedWith: [8, 1, 2, 3],
move: function() {
return `
${ this.name }and
${this.id }and
${ this.form }and
${ this.points }and
${ this.tactics }and
${ this.played }and
${ this.gameset }and
${ this.playedWith }`
}
};
console.log(b.move())
for (var w in b) {
console.log(${w}:${b.move()})
}
Your best bet is to just do this:
Object.keys(data).forEach((key, i) => {
console.log("Property: " + key, "\nValue: ", data[key])
})
This will give you the property and value. You can also tweak this to have more robust logic for finding or parsing different data types.
You have an array in one of your properties. You can handle it like this.
let clubs = [ {}, {} ]
clubs.forEach((club, i) => {
if (club && Array.isArray(club) || typeof club !== 'object') {
return;
// Stop loop bc club is not an object
}
Object.keys(club).forEach((key, i) => { // Iterate through all the object properties
console.log("Property: " + key, "\nValue: ", club[key])
if (Array.isArray(club[key]) { // Add more conditions or look for certain property names (keys).
console.log('Length of array from property: ', club[key].length)
club[key].map(el => console.log(key + ' value: ' + el))
// You can choose how you want to handle this.
/*
Expected output:
playedWith value: 8
playedWith value: 1
playedWith value: 2
playedWith value: 3
*/
}
})
})
you cant get the array length using width.
try this,
var clubs = [{name: 'Club 01', id:1, form: 45, points: 0, tactics: 'neutral', played: 0, gameset: 0, playedWith: [8,1,2,3]}]
for (let club of clubs) {
for(let playedWothId of club.playedWith){
console.log(playedWothId);
}
}
Related
I am trying to make function to get top3 objects from an array based by props. My site can't load up so i think this function runs endlessly but i cant figure out why.
renderItems = (items) => {
let top3 = []
let tempArr = items
let allNumbers = []
while (top3.length < 3){
allNumbers = []
for(let i = 0; i < tempArr.length; i++){
allNumbers = [...allNumbers, tempArr[i].hearts]
}
const result = tempArr.filter(i => i.hearts === Math.max(...allNumbers))
top3 = [...top3, ...result]
let countOfdeleted = 0
for(let i = 0; i < result.length; i++){
tempArr.splice(result[i].id-countOfdeleted, 1)
countOfdeleted++
}
for(let i = 0; i < tempArr.length; i++){
tempArr[i].id = i
}
}
console.log(top3);
}
This answer is based on the assumption that 'items' is an array of objects and that each object in 'items' will have at-least 2 props namely 'id' and 'hearts'.
Further, there is no clarity on the significance of 'countOfdeleted' and 'tempArr'. Hence, it is assumed
that one needs to know how many elements of the 'items' array were not included (in the top3) as 'countOfdeleted'
that the remaining objects need to have their 'id' updated (based on index)
With the aforementioned assumptions, the below should implement the required logic:
const items = [
{ id: 0, hearts: 5 }, { id: 1, hearts: 4 }, { id: 2, hearts: 5 },
{ id: 3, hearts: 3 }, { id: 4, hearts: 5 }, { id: 5, hearts: 2 },
{ id: 6, hearts: 2 }, { id: 7, hearts: 1 }, { id: 8, hearts: 4 }
];
const getTop3 = (arr = items) => {
const maxVal = arr.reduce((fin, itm) => itm.hearts > fin ? itm.hearts : fin, 0);
const topAll = arr.filter(obj => obj.hearts === maxVal);
const sansTop3 = arr
.filter(obj => obj.hearts !== maxVal)
.map((obj, idx) => ({...obj, id: idx}));
console.log('countOfDeleted: ', arr.length - (topAll.length > 3 ? topAll.length : 3));
console.log('rest with updated-id (tempArr): ', sansTop3);
return topAll.length > 3 ? topAll.slice(0, 3) : [...topAll];
};
console.log('\ntop3:\n^^^^\n', getTop3());
Approach / Explanation
Find the 'maximum-value' (maxVal) based on the prop ('hearts')
Find all objects which have the props matching maxVal (stored in array 'topAll')
[Optional: Gather remaining 'items' elements and update their 'id' in 'sansTop3' array, to match the 'tempArr' in the question]
[Optional: Determine the number of 'items' deleted, to match countOfdeleted in the question]
If more than 3 elements have props ('heart') matching 'maxVal', return only 3; otherwise, return the all top-value element/s
I'm trying to write a program that generates every single item based on my JSON structure and giving each combination an individual number. I found a function on here that so far does its job listing out every combination for me, however I cannot decipher the code to the point I actually even understand what it does. It gives me all the items, listen like Key : Value but honestly I have no idea what part of the code does what and I cannot access it in order to build in my giving them unique numbers. This is the code that I found on here (lost the thread to it):
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var input = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } },
cartesian = { eachBook: getCartesian(input.bookSet) };
It's just written in a too advanced syntax for me to remotely understand where I have to insert myself to make any calculations. I guess what I'm asking for would be either an explanation or a somewhat more understandable and modifyable code. I definitely need to run through all elements like this is doing and the output looks great from what I could tell so far, I just need to somehow calculate the keys and have an output of a number derived of each object's elements' combined keys.
An example would be book 243 for title 2, author 4 and publisher 3. I hope anyone can make sense of this. Thanks a lot!
EDIT: Included my own data and desired output. The combinations I displayed don't need to make sense.
var Product = {
json: { Product : {
assortment: [
{
name: "Yoghurt",
Flavor: ["natural", "honey", "stracciatella"],
Kind: ["greek", "soy"],
},
{
name: "Sauce",
},
{
name: "Milk Drink",
}
],
Brand: ["Oatly", "Dannon"],
Containment: ["Cup", "Jar"]
}}};
My output I'd like to generate the combinations of all of those and ultimately calculate the numbers on the right in the following screenshot
Given C_1 and C_2 two sets
The cartesian product of C_1 and C_2
is given by C_1 x C_2 = {(c_1_i,c_2_j) for c_1_i in C_1, c_2_j in C_2}
You can build C_1 x C_2 x C_3 by considering (C_1 x C_2) (that you calculated before) and "adjoining" each elem of C_3 to a tuple of C_1 x C_2
And so forth
const cartesianProduct = (C, D) => {
const res = []
C.forEach(c => {
D.forEach(d => {
// in case the tuple contains only one element (the initialization)
// make the elmeent into a tuple
const tuple = Array.isArray(c) ? c : [c]
res.push([...tuple,d])
})
})
return res
}
const nCartesianProduct = (Cs_n) => {
// we adjoin each elem of C_i and we "grow"
return Cs_n.reduce((res, C_i) => cartesianProduct(res, C_i))
}
console.log(nCartesianProduct([['b1', 'b2', 'b3'], ['t1', 't2'], ['a'], ['p']]))
Here is my attempt to lay in a simple terms:
Lets assume an example of
const sets = [ [1], [1,2], [1,2,3] ]
Possible combinations may be logged as following:
1 1 1 1 2 1
1 1 2 -> 1 2 2
1 1 3 1 2 3
Lets think of it as a clock, where last row will increase the value of previous row, once it reaches its maximum. In another words: lets increase i position of the last row and when over the limit -> drop it to zero and increase sibling instead, where if sibling is over the top -> repeat.
Consider the following code:
let sets = [[1,2], [1,2,3], [1,2,3,4], [1,2,3,4,5] ];
let state = sets.map( () => 0 );
console.log(sets, state);
function handleIncreament(i){
if( state[i] >= sets[i].length){
if(i-1 < 0) {
console.log('end of the row');
return false;
}
state[i] = 0;
state[i-1] += 1;
return handleIncreament(i-1);
}
else {
return true;
}
}
while( handleIncreament(state.length - 1) ){
console.log( state );
state[state.length - 1]++;
}
Above will log as follows:
(4) [Array(2), Array(3), Array(4), Array(5)] (4) [0, 0, 0, 0]
(4) [0, 0, 0, 0]
(4) [0, 0, 0, 1]
(4) [0, 0, 0, 2]
(4) [0, 0, 0, 3]
(4) [0, 0, 0, 4]
(4) [0, 0, 1, 0]
(4) [0, 0, 1, 1]
(4) [0, 0, 1, 2]
...
(4) [1, 2, 3, 4]
end of the row
4
With that lets apply it to your example:
const test = { bookSet: { book: ["book1", "book2", "book3"], title: ["title1", "title2"], author: ["author1"], publisher: ["publisher1"] } };
sets = Object.values(test.bookSet);
state = sets.map( () => 0 );
console.log(sets, state);
const matches = [];
while( handleIncreament(state.length - 1) ){
const match = sets[0][state[0]] + ' ' + sets[1][state[1]] + ' ' + sets[2][state[2]] + ' ' + sets[3][state[3]];
matches.push( match );
state[state.length - 1]++
}
console.log(matches);
And expect to get the following:
["book1 title1 author1 publisher1", "book1 title2 author1 publisher1", "book2 title1 author1 publisher1", "book2 title2 author1 publisher1", "book3 title1 author1 publisher1", "book3 title2 author1 publisher1"]
You could take the above data without superfluous parts and simplify the result by creating a flat array of the nested properties.
The numbers of the result picture are not incuded, because of the missing relation of each value to the given data set.
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var data = {
assortment: [
{
name: "Yoghurt",
Flavor: ["natural", "honey", "stracciatella"],
Kind: ["greek", "soy"],
},
{
name: "Sauce",
},
{
name: "Milk Drink",
}
],
Brand: ["Oatly", "Dannon"],
Containment: ["Cup", "Jar"]
},
result = getCartesian(data)
.map(({ assortment: { name, Flavor = '', Kind = '' }, d = '', Brand, f = '', Containment, h = '', i = '', j = '' }) =>
[name, Flavor, Kind, d, Brand, f, Containment, h, i, j]);
console.log(result.length);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
how to count the value of object in new object values
lets say that i have json like this :
let data = [{
no: 3,
name: 'drink'
},
{
no: 90,
name: 'eat'
},
{
no: 20,
name: 'swim'
}
];
if i have the user pick no in arrays : [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]
so the output should be an array
[
{
num: 3,
total: 11
},
{
num: 90,
total: 1
},
{
num:20,
total: 4
}
];
I would like to know how to do this with a for/of loop
Here is the code I've attempted:
let obj = [];
for (i of arr){
for (j of data){
let innerObj={};
innerObj.num = i
obj.push(innerObj)
}
}
const data = [{"no":3,"name":"drink"},{"no":90,"name":"eat"},{"no":20,"name":"swim"}];
const arr = [3,3,3,3,3,3,3,3,3,3,3,20,20,20,20,80,80];
const lookup = {};
// Loop over the duplicate array and create an
// object that contains the totals
for (let el of arr) {
// If the key doesn't exist set it to zero,
// otherwise add 1 to it
lookup[el] = (lookup[el] || 0) + 1;
}
const out = [];
// Then loop over the data updating the objects
// with the totals found in the lookup object
for (let obj of data) {
lookup[obj.no] && out.push({
no: obj.no,
total: lookup[obj.no]
});
}
document.querySelector('#lookup').textContent = JSON.stringify(lookup, null, 2);
document.querySelector('#out').textContent = JSON.stringify(out, null, 2);
<h3>Lookup output</h3>
<pre id="lookup"></pre>
<h3>Main output</h3>
<pre id="out"></pre>
Perhaps something like this? You can map the existing data array and attach filtered array counts to each array object.
let data = [
{
no: 3,
name: 'drink'
},
{
no:90,
name: 'eat'
},
{
no:20,
name: 'swim'
}
]
const test = [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]
const result = data.map((item) => {
return {
num: item.no,
total: test.filter(i => i === item.no).length // filters number array and then checks length
}
})
You can check next approach using a single for/of loop. But first I have to create a Set with valid ids, so I can discard noise data from the test array:
const data = [
{no: 3, name: 'drink'},
{no: 90, name: 'eat'},
{no: 20, name: 'swim'}
];
const userArr = [3,3,3,3,3,3,3,3,7,7,9,9,3,3,3,90,20,20,20,20];
let ids = new Set(data.map(x => x.no));
let newArr = [];
for (i of userArr)
{
let found = newArr.findIndex(x => x.num === i)
if (found >= 0)
newArr[found].total += 1;
else
ids.has(i) && newArr.push({num: i, total: 1});
}
console.log(newArr);
I am going to merge 2 array with one array key and other array with key and get only other array value and create final one array in the last. i have write some logic here but i am just put first array key push but other array value can't push in the final array. so anyone know how can do that then please let me here. here i have listed my code with array.
This is my first array=>
var arr = ["fullName","username","biography","externalurl","followerCount","followingCount","medaiCount"];
This is my other array =>
var FinalFilterArray = [ { fullName: 'love',
username: 'lo.ve632',
biography: '',
externalUrl: '',
followerCount: 13,
followingCount: 129,
mediaCount: 0 },
{ fullName: 'abc',
username: '#abc',
biography: '',
externalUrl: '',
followerCount: 289,
followingCount: 262,
mediaCount: 0 }];
This is my logic =>
var ExcelData = [];
for (var i = 0; i < FinalFilterArray.length; i++) {
console.log("f" + FinalFilterArray.length)
if (i == 0) {
ExcelData[i] = arr
}
else {
var key = [];
for (var j = 0; j < arr.length; j++) {
console.log("j " + arr[j]) if(FinalFilterArray[i] == arr[j]){key.push[FinalFilterArray[i].arr[j]]}
}
ExcelData[i] = [key]
}
}
my Expected o\p =>
[[ 'fullName',
'username',
'biography',
'externalUrl',
'followerCount',
'followingCount',
'mediaCount' ],
['love','lo.ve632','','','13','129','0'] ,
['abc','#abc','','','289','262','0']]
finalArr = [ arr , ...FinalFilterArray.map(item => arr.map(key => item[key])) ]
If you want an es5 solution to this, use
finalArr = [arr].concat(FinalFilterArray.map(function(item){
return arr.map(function(key) {
return item[key]
})
})
a collection is returning 11 items as follows;
( 1, "Ball", "Result1")
( 2, "Ball", " Result2")
( 3, "Ball", " Result3")
( 4, "Ball", " Result4")
( 5, "Ball", " Result5")
( 6, "Ball", " Result6")
( 7, "Ball", " Result7")
( 8, "Ball", " Result8")
( 9, "Pool", " Pool 1")
( 10, "Pool", " Pool 2")
( 11, "Pool", " Pool 3")
I want to store them, group them as four items.. so that my array looks like this
var data = [];
data.push({
myclass: "First4",
schedule: [ {
id : '1',
gameType: 'Ball',
result: 'Result11'
}, {
id: '2',
gameType: 'Ball',
result: 'Result2'
},........... ]
});
//second group
data.push({
divClass : "second4",
items : [ {
id : '5'
gameType: 'Ball',
result: 'Result5'
}, {
id : ''
gameType: 'Ball',
result: 'Result6
} ]
});
how can i write a for loop so that i can achieve the same result dynamically instead of writing the push manually
for(var i = 0; i < collLength; i++){
// do push 1 with first four //data.push(class, sheculde first 4 items, result)
// do second push with second four
// do third push with the remaining
}
var data = [];
for(var i = 0; i < collLength; i+=4) {
data.push({
divClass: "group" + (i / 4),
items: collection.slice(i, i + 4).map(function(item) {
return {id:item[0], gameType:item[1], result:item[2]};
})
});
}
var indata = [...]; // this is filled with your list of objects.
var outdata = [ ];
var n = indata.length;
for (var i = 0; i < n; i += 4)
{
outdata.push({
class: 'group' + outdata.length,
items: indata.slice(i, i + 4)
});
}
var indata = [...]; // this is filled with your list of objects.
var outdata = [ ];
function mapper(element, i)
{
var j = Math.floor(i / 4);
if (outdata[j] == undefined)
outdata[j] = { class: 'group' + j, items: [ ] };
outdata[j].items.push(element);
}
indata.map(mapper);
Here's a way using .reduce().
var data = collection.reduce(function(arr, obj, i) {
return i % 4 ? arr :
arr.concat({
divClass: "group" + (i / 4),
items: collection.slice(i, i + 4).map(function(item) {
return {id:item[0], gameType:item[1], result:item[2]};
})
});
}, []);