What is the good way to loop through a javascript array? [duplicate] - javascript

This question already has answers here:
Split array into chunks
(73 answers)
Closed 5 years ago.
Consider the following JavaScript Array:
const allRows = [
{id: 1, name: Name 1},
{id: 2, name: Name 1},
{id: 3, name: Name 1},
{id: 4, name: Name 1},
{id: 5, name: Name 1},
{id: 6, name: Name 1},
{id: 7, name: Name 1},
{id: 8, name: Name 1},
{id: 9, name: Name 1},
{id: 10, name: Name 1},
{id: 11, name: Name 1},
{id: 12, name: Name 1},
{id: 13, name: Name 1},
{id: 14, name: Name 1},
{id: 15, name: Name 1},
{id: 16, name: Name 1},
{id: 17, name: Name 1},
{id: 18, name: Name 1},
{id: 19, name: Name 1},
{id: 20, name: Name 1},
{id: 21, name: Name 1},
{id: 22, name: Name 1},
{id: 23, name: Name 1},
{id: 24, name: Name 1},
{id: 25, name: Name 1},
{id: 26, name: Name 1},
{id: 27, name: Name 1},
{id: 28, name: Name 1},
{id: 29, name: Name 1},
{id: 30, name: Name 1},
];
// want to loop through the array and convert it to the array as written below
let rowsPaginated = [
[
{id: 1, name: Name 1},
{id: 2, name: Name 1},
{id: 3, name: Name 1},
{id: 4, name: Name 1},
{id: 5, name: Name 1},
{id: 6, name: Name 1},
{id: 7, name: Name 1},
{id: 8, name: Name 1},
{id: 9, name: Name 1},
{id: 10, name: Name 1}
],
[
{id: 11, name: Name 1},
{id: 12, name: Name 1},
{id: 13, name: Name 1},
{id: 14, name: Name 1},
{id: 15, name: Name 1},
{id: 16, name: Name 1},
{id: 17, name: Name 1},
{id: 18, name: Name 1},
{id: 19, name: Name 1},
{id: 20, name: Name 1}
],
[
{id: 21, name: Name 1},
{id: 22, name: Name 1},
{id: 23, name: Name 1},
{id: 24, name: Name 1},
{id: 25, name: Name 1},
{id: 26, name: Name 1},
{id: 27, name: Name 1},
{id: 28, name: Name 1},
{id: 29, name: Name 1},
{id: 30, name: Name 1}
]
];
I am thinking to convert this way -
for (let i = 0; i < allRows.length; i++) {
console.log(allRows[i]);
}
But I don't think it will be a good way to do it.
What is the best way to loop through the allRows array and convert as rowsPaginated array?

Use array's slice() with the size you want to cut from the array. Try the following:
const allRows = [
{id: 1, name: 'Name 1'},
{id: 2, name: 'Name 1'},
{id: 3, name: 'Name 1'},
{id: 4, name: 'Name 1'},
{id: 5, name: 'Name 1'},
{id: 6, name: 'Name 1'},
{id: 7, name: 'Name 1'},
{id: 8, name: 'Name 1'},
{id: 9, name: 'Name 1'},
{id: 10, name: 'Name 1'},
{id: 11, name: 'Name 1'},
{id: 12, name: 'Name 1'},
{id: 13, name: 'Name 1'},
{id: 14, name: 'Name 1'},
{id: 15, name: 'Name 1'},
{id: 16, name: 'Name 1'},
{id: 17, name: 'Name 1'},
{id: 18, name: 'Name 1'},
{id: 19, name: 'Name 1'},
{id: 20, name: 'Name 1'},
{id: 21, name: 'Name 1'},
{id: 22, name: 'Name 1'},
{id: 23, name: 'Name 1'},
{id: 24, name: 'Name 1'},
{id: 25, name: 'Name 1'},
{id: 26, name: 'Name 1'},
{id: 27, name: 'Name 1'},
{id: 28, name: 'Name 1'},
{id: 29, name: 'Name 1'},
{id: 30, name: 'Name 1'},
];
let rowsPaginated = [];
var i, j, size = 10;
for (i = 0, j = allRows.length; i < j; i += size) {
rowsPaginated.push(allRows.slice(i, i+size));
}
console.log(rowsPaginated);

Try following code, I corrected your array was few mistakes:
const allRows = [
{id: 1, name: "Name1"},
{id: 2, name: "Name1"},
{id: 3, name: "Name1"},
{id: 4, name: "Name1"},
{id: 5, name: "Name1"},
{id: 6, name: "Name1"},
{id: 7, name: "Name1"},
{id: 8, name: "Name1"},
{id: 9, name: "Name1"},
{id: 10, name: "Name1"},
{id: 11, name: "Name1"},
{id: 12, name: "Name1"},
{id: 13, name: "Name1"},
{id: 14, name: "Name1"},
{id: 15, name: "Name1"},
{id: 16, name: "Name1"},
{id: 17, name: "Name1"},
{id: 18, name: "Name1"},
{id: 19, name: "Name1"},
{id: 20, name: "Name1"},
{id: 21, name: "Name1"},
{id: 22, name: "Name1"},
{id: 23, name: "Name1"},
{id: 24, name: "Name1"},
{id: 25, name: "Name1"},
{id: 26, name: "Name1"},
{id: 27, name: "Name1"},
{id: 28, name: "Name1"},
{id: 29, name: "Name1"},
{id: 30, name: "Name1"}
];
let rowsPaginated = [];
let j = 0;
for (let i = 0, j = allRows.length; i < j; i += 10) {
rowsPaginated.push(allRows.slice(i, i+10));
}
console.log(rowsPaginated);

Related

Count the number of items in each category within a JavaScript object

I have an array containing several hundred objects, each of which has a category. I wish to return an object that lists out the categories with a count of the number of items for each category.
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
How would I loop through the object and create a new object that contains just the two categories and how many of each per category?
Desired output:
{vehicle: 4, animal: 3}
Code:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
arr.forEach((v) => {
const tst = v.category;
console.log(tst);
if (tst in final){
console.log('found one');
}
});
//console.log(final);
You can use reduce
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const categories = arr.reduce((acc, cur) => {
acc[cur.category] = (acc[cur.category] || 0) + 1
return acc;
}, {})
console.log(categories)
edit:
Now, after a year a would wrt this like that
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const categories = arr.reduce((acc, cur) => Object.assign(acc, {
[cur.category]: (acc[cur.category] || 0) + 1,
}), {})
console.log(categories)
It looks like the category will always exist, so you don't need to check whether it exists, but what it contains; take what it contains and increment that property on the final object:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
for (const { category } of arr) {
final[category] = (final[category] || 0) + 1;
};
console.log(final);
You have the right idea regarding looping over the array and checking if the category was already encountered. What you're missing is initializing a counter when you find a new category and incrementing it the next time that category is encountered:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
arr.forEach((v) => {
const cat = v.category;
if (cat in final) {
final[cat]++;
} else {
final[cat] = 1;
}
});
console.log(final);
const arr = [
{ id: 1, name: 'ford', category: 'vehicle' },
{ id: 2, name: 'pig', category: 'animal' },
{ id: 3, name: 'dog', category: 'animal' },
{ id: 4, name: 'chev', category: 'vehicle' },
{ id: 5, name: 'cat', category: 'animal' },
{ id: 6, name: 'jeep', category: 'vehicle' },
{ id: 7, name: 'honda', category: 'vehicle' },
]
// this will hold the results
const result = {}
for (const item of arr) {
// we have not encountered such category before
if (result[item.category] === undefined) {
// setting this category to 1
result[item.category] = 1
// we encountered such category before
} else {
// addint +1 to it
result[item.category] += 1
}
}
console.log(result)

Match spanish words replace method

this functions searchs names or categories of this array of objects, i need to ignore spanish letters with 'acento' (for example: i need to match 'Taragüí' if i write taragui), i solve this with the string replace() method, my question: Is there a way to solve this with some unicode method? Thanks in advance.
var fromDB = [
{id: 1, name: 'Almendras', category: 'Frutos secos', price: 25, amount: 0, description: 'asd'},
{id: 2, name: 'Nueces', category: 'Frutos secos', price: 10, amount: 0, description: 'asd'},
{id: 3, name: 'Mermelada', category: 'Jam', price: 15, amount: 0, description: 'asd'},
{id: 4, name: 'Alfajor', category: 'Sweet', price: 20, amount: 0, description: 'asd'},
{id: 5, name: 'Queso', category: 'UwU', price: 45, amount: 0, description: 'asd'},
{id: 6, name: 'Arandanos', category: 'Fruta', price: 50, amount: 0, description: 'asd'},
{id: 7, name: 'Maracuya', category: 'Fruta', price: 50, amount: 0, description: 'asd'},
{id: 8, name: 'Chocolate', category: 'Sweet', price: 50, amount: 0, description: 'asd'},
{id: 9, name: 'Mascarpone', category: 'UwU', price: 50, amount: 0, description: 'asd'},
{id: 9, name: 'Taragüí', category: 'UwU', price: 50, amount: 0, description: 'asd'}
];
const input = document.querySelector('input');
input.addEventListener('input', updateValue);
function updateValue(e) {
realTimeInputValue = e.target.value.toLowerCase();
let productsMatch = fromDB.filter(x => x.name.toLowerCase().replace('á', 'a').replace('é', 'e').replace('í', 'i').replace('ó', 'o').replace('ú', 'u').replace('ü', 'u').includes(realTimeInputValue))
if(productsMatch.length){
console.log(productsMatch)
} else {
let categoriesMatch = fromDB.filter(x => x.category.toLowerCase().includes(realTimeInputValue))
console.log(categoriesMatch);
}
}
<input type="text" placeholder="Enter some text" name="name"/>

How to find objects in array where inner array might include other objects by using lodash

I have the following arrays:
const tasks = [
{id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},
{id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 11, name: 's'}]},
{id: 2, name: 'c', tags: []},
{id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},
{id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]},
]
const tags = [
{id: 0, name: 'q'},
{id: 1, name: 'w'},
{id: 2, name: 'e'},
{id: 3, name: 'r'},
{id: 4, name: 't'},
{id: 7, name: 'i'},
{id: 11, name: 's'}
]
let selectedTags = [0, 5]
selectedTags is an Array of indexes of tags Array. Now I need to find all objects in tasks Array, where property tags includes any of the selected tags. So in this case the output should be:
let result = [
{id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},
{id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},
{id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]}
]
I tried to do something like this:
let result= []
_.forEach(selectedTags, index => {
const tagId = tags[index].id
result = _.filter(tasks, task => _.some(task.tags, ['tag.id', tagId]))
})
but I'm ending up with an empty array. I tried to use map, find and some other lodash methods, but so far nothing worked.
Any ideas, please?
You're reassigning the filtered array in each iteration, also you're passing to the function .some an array, however, you should pass a key-value object instead.
The following approach used two nested calls of function .some for checking tags.id vs selectedTag ids,
const tasks = [ {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]}, {id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 11, name: 's'}]}, {id: 2, name: 'c', tags: []}, {id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]}, {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]}],
tags = [ {id: 0, name: 'q'}, {id: 1, name: 'w'}, {id: 2, name: 'e'}, {id: 3, name: 'r'},{id: 4, name: 't'}, {id: 7, name: 'i'}, {id: 11, name: 's'}],
selectedTags = [0, 5],
result = _.filter(tasks, ({tags: itags}) => _.some(itags, ({id}) => _.some(selectedTags, i => tags[i].id === id)));
console.log(result);
.as-console-wrapper {min-height: 100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script>
You need to use filter() with nested some()
const tasks = [
{id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},
{id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 11, name: 's'}]},
{id: 2, name: 'c', tags: []},
{id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},
{id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]},
]
const tags = [
{id: 0, name: 'q'},
{id: 1, name: 'w'},
{id: 2, name: 'e'},
{id: 3, name: 'r'},
{id: 4, name: 't'},
{id: 7, name: 'i'},
{id: 11, name: 's'}
]
let selectedTags = [0, 5]
const res = tasks.filter(({tags}) =>
tags.some(tag =>
selectedTags.some(index => tags[index].name === tag.name)
)
);
console.log(res)

move key to sub array js [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have an array of objects grouped by Name like this:
[
{
Name: 'Color',
Data:[{Id: 1, Name: 'Red'},
{Id: 2, Name: 'Yellow'},
{Id: 3, Name: 'Blue'},
{Id: 4, Name: 'Green'},
{Id: 7, Name: 'Black'}]
}, {
Name: 'Size',
Data:[{Id: 8, Name: 'S'},
{Id: 11, Name: 'M'},
{Id: 12, Name: 'L'},
{Id: 13, Name: 'XL'},
{Id: 14, Name: 'XXL'}]
}
]
I would like to transform this into a heavy array like this:
[
{Id: 1, Name: 'Red', optionName: 'Color'},
{Id: 2, Name: 'Yellow', optionName: 'Color'},
{Id: 3, Name: 'Blue', optionName: 'Color'},
{Id: 4, Name: 'Green', optionName: 'Color'},
{Id: 7, Name: 'Black', optionName: 'Color'},
{Id: 8, Name: 'S', optionName: 'Size'},
{Id: 11, Name: 'M', optionName: 'Size'},
{Id: 12, Name: 'L', optionName: 'Size'},
{Id: 13, Name: 'XL', optionName: 'Size'},
{Id: 14, Name: 'XXL', optionName: 'Size'}
]
How to do it in javascript/ES6?
You can use .map(), .concat() and Object.assign() methods to get the resultant array:
let data = [
{Name: 'Color', Data:[{Id: 1, Name: 'Red'}, {Id: 2, Name: 'Yellow'}, {Id: 3, Name: 'Blue'}, {Id: 4, Name: 'Green'}, {Id: 7, Name: 'Black'}]},
{Name: 'Size', Data:[{Id: 8, Name: 'S'}, {Id: 11, Name: 'M'}, {Id: 12, Name: 'L'}, {Id: 13, Name: 'XL'}, {Id: 14, Name: 'XXL'}]}
];
let result = [].concat(
...data.map(({Name, Data}) => Data.map(o => Object.assign({}, o, {optionName: Name})))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use array#reduce with array#forEach.
const data = [ { Name: 'Color', Data:[{Id: 1, Name: 'Red'}, {Id: 2, Name: 'Yellow'}, {Id: 3, Name: 'Blue'}, {Id: 4, Name: 'Green'}, {Id: 7, Name: 'Black'}] }, { Name: 'Size', Data:[{Id: 8, Name: 'S'}, {Id: 11, Name: 'M'}, {Id: 12, Name: 'L'}, {Id: 13,Name: 'XL'}, {Id: 14, Name: 'XXL'}] } ],
result = data.reduce((r, {Name: optionName,Data}) => {
Data.forEach(({Id, Name}) => r.push({Id,Name, optionName}));
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can also able to do it using forEach. like below.
var s = [{Name:'Color',Data:[{Id:1,Name:'Red'},{Id:2,Name:'Yellow'},{Id:3,Name:'Blue'},{Id:4,Name:'Green'},{Id:7,Name:'Black'}]},{Name:'Size',Data:[{Id:8,Name:'S'},{Id:11,Name:'M'},{Id:12,Name:'L'},{Id:13,Name:'XL'},{Id:14,Name:'XXL'}]}];
var y=[];
s.forEach(x=>x.Data.forEach(z=>{
z['optionName'] = x.Name;
y.push(z);
}));
console.log(y);

How to use same tokeninput for multiple fields

I have a table in which a column(say names) consists of text field. I need same tokeninput for all the rows.
<script type="text/javascript">
$(function(){
$('#names').tokenInput([
{id: 7, name: "Super Mario"},
{id: 11, name: "Battletoads"},
{id: 13, name: "Pong"},
{id: 17, name: "The Legend of Zelda"},
{id: 19, name: "Metroid"},
{id: 23, name: "Donkey Kong Country"},
{id: 29, name: "Super Smash Bros."},
{id: 32, name: "Star Fox"},
{id: 35, name: "Starcraft"},
{id: 37, name: "Pokemon"},
{id: 38, name: "Minecraft"},
{id: 41, name: "The Sims"},
{id: 43, name: "Final Fantasy"},
{id: 44, name: "Resident Evil"},
{id: 46, name: "Kingdom Hearts"},
{id: 47, name: "Tetris"},
{id: 48, name: "Grand Theft Auto"},
{id: 51, name: "World of Warcraft"},
{id: 53, name: "Metal Gear Solid"},
{id: 54, name: "Civilization"},
{id: 56, name: "Pac-Man"},
{id: 59, name: "Animal Crossing"},
{id: 62, name: "Spyro the Dragon"},
{id: 64, name: "Crash Bandicoot"},
{id: 65, name: "Sonic the Hedgehog"},
{id: 72, name: "Tomb Raider"},
{id: 77, name: "Mortal Kombat"},
{id: 81, name: "Space Invaders"}
], {
theme: "facebook",
noResultsText: "Nothin' found.",
searchingText: "Searching...",
preventDuplicates: true
});
});
</script>
I need the above token input for multiple fields .
EX : say i have a table with a filed called Names. So i need for all the Name filed in each i want to use Same token input
Below is the Html
<tr><td><input type="text" id="names"></td></tr>
<tr><td><input type="text" id="names1"></td></tr>
<tr><td><input type="text" id="names2"></td></tr>
I am able to use for one text field, but i need it same for all the rows
Demo link: http://codepen.io/jakestuts/full/IBmja
You'll need to initialise them all individually - use a for loop.
var tokens = [
{id: 7, name: "Super Mario"},
{id: 11, name: "Battletoads"},
{id: 13, name: "Pong"},
etc...
{id: 72, name: "Tomb Raider"},
{id: 77, name: "Mortal Kombat"},
{id: 81, name: "Space Invaders"}
];
for (var i = 1; i <= 3; i++){
$('#names' + i).tokenInput(tokens, {
theme: "facebook",
noResultsText: "Nothin' found.",
searchingText: "Searching...",
preventDuplicates: true
});
}

Categories

Resources