how to get all items with same values in array? - javascript

I have a json with some characters, and need to print all characters with 3 stars (example)
but how?
json example:
[
{
"name":"Naruto Uzumaki",
"anime":"Naruto",
"star":"2",
"ID":0
},
{
"name":"Son Goku",
"anime":"Dragon Ball",
"star":"3",
"ID":1
},
{
"name":"Monkey D. Luffy",
"anime":"One Piece",
"star":"2",
"ID":2
},
{
"name":"Naruto Uzumaki (Sage Mode)",
"anime":"Naruto",
"star":"3",
"ID":3
}
]
I'm looking for a method to print them all, and be able to randomize between them too
like:
console.log(unit)//{"name":"son Goku"....},{"name":"Naruto"....}
random = 0;
unit = unit[random]
console.log(unit)//{"name":"son Goku"....}

You can use The filter() method to create a new array with your condition from your previous array.
const formatedara = data.filter(x => x.star === "3");
From this new array, you can get any specific object by -
formatedara[index];
const data = [{
name: "Naruto Uzumaki",
anime: "Naruto",
star: "2",
ID: 0,
},
{
name: "Son Goku",
anime: "Dragon Ball",
star: "3",
ID: 1,
},
{
name: "Monkey D. Luffy",
anime: "One Piece",
star: "2",
ID: 2,
},
{
name: "Naruto Uzumaki (Sage Mode)",
anime: "Naruto",
star: "3",
ID: 3,
},
];
const formatData = data.filter((x) => x.star === "3");
console.log(formatData);

You could use the array.map(x => x.star === "3") method. That will create a new array with the items that correspond to your parameters. Also, you're storing the star number as a string, which is not ideal if you want to do maths with it later.

do u want like this ?
unit.forEach((e)=>{
if (e.star == "3") {
console.log(JSON.stringify(e));
//do sth
}
});

var objJson = JSON.parse('[{"name": "Naruto Uzumaki","anime": "Naruto","star": "2", "ID": 0}, { "name": "Son Goku","anime": "Dragon Ball","star": "3","ID": 1 }, {"name": "Monkey D. Luffy", "anime": "One Piece","star": "2","ID": 2},{"name": "Naruto Uzumaki (Sage Mode)","anime": "Naruto","star": "3","ID": 3}]');
var filteredJson = objJson.filter(x => x.star === "3");
console.log(filteredJson);
var random = 0;
filteredJson = filteredJson[random]
console.log(filteredJson);

You could use basic methods also but better is using filter method.
var array = [];
for(i = 0; i < sample.length; i++) {
if (sample[i].star === "3") {
array.push(sample[i]);
}
}
console.log(array)

print all characters with 3 stars (example) but how
for a method to print them all, and be able to randomize between them too like
Just split your problem in multiple steps and it will become clear.
Get characters with 3 stars.
Print characters.
Get a random character from a set of characters.
const characters = [
{
"name":"Naruto Uzumaki",
"anime":"Naruto",
"star":"2",
"ID":0
},
{
"name":"Son Goku",
"anime":"Dragon Ball",
"star":"3",
"ID":1
},
{
"name":"Monkey D. Luffy",
"anime":"One Piece",
"star":"2",
"ID":2
},
{
"name":"Naruto Uzumaki (Sage Mode)",
"anime":"Naruto",
"star":"3",
"ID":3
}
];
// Find all with 3 stars
const threeStarChars = characters.filter(hasTreeStar);
// Print those characters
threeStarChars.forEach(printCharacter);
// Randomize characters
const random3StarCharacter = randomSequenceOf(threeStarChars);
const anyRandomCharacter = randomSequenceOf(characters);
document.querySelector('button:first-child').addEventListener('click', () => printCharacter(random3StarCharacter()));
document.querySelector('button:nth-child(2)').addEventListener('click', () => printCharacter(anyRandomCharacter()));
function hasTreeStar(character) {
return character.star === '3';
}
function printCharacter(character) {
// Some printing logic
console.log(JSON.stringify(character, null, 4));
}
function randomSequenceOf(items) {
const all = [...items];
const current = [...items];
return function () {
if (!current.length) current.push(...items);
return current.splice(randomBetween(0, current.length), 1).pop();
};
}
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
<button>Print random 3 star</button>
<button>Print any random</button>

Related

how to update a particular json data object which belongs to browser local-storage

This is Browser localstorage Object referred as dataset
let dataset = localStorage.getItem('dataset') !== null ? leech : [];
[
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
This is the initial data object available I want to add more field to a particular id.
This is what I want :
[
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd",
"status":1
}
]
This my code to find the particular id
const user = dataset.find(user => user.id == 456);
Now how can I add status to user and update the user in the dataset?
You've already found the user by using Array.prototype.find() so all you need to do then is add the status property
// const dataset = JSON.parse(localStorage.getItem("dataset"))
const dataset = [{"id":123,"name":"abc"},{"id":456,"name":"bcd"}]
const user = dataset.find(({ id }) => id === 456)
if (user) {
user.status = 1
}
console.info(dataset)
.as-console-wrapper { max-height: 100% !important }
If you then want to store the modified data back into localStorage, use localStorage.setItem() and JSON.stringify()
localStorage.setItem("dataset", JSON.stringify(dataset))
If you want keep dataset initial value, and would like to get a new array, you can use Array.reduce() method.
const dataset = [
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
const output = dataset.reduce((acc, cur) => {
if (cur.id === 456) cur.status = 1;
acc.push(cur);
return acc;
}, []);
console.log(output);
If you want to update dataset, you can use Array.forEach() method.
const dataset = [
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
dataset.forEach(user => {
if (user.id === 456) user.status = 1;
});
console.log(dataset);
You could do with Array#Findindex with callback return function. so could pass the originaldata,searchId and update object. In this method you could updated object easily
Why i suggest findIndex
Because findindex not running entire loop or iteration. If the match
detect on first iteration they will break the loop and returning the
result.For long iteration its more faster than other loop (reduce,forEach)
const data = [ { "id": 123, "name": "abc" }, { "id": 456, "name": "bcd" } ]
function update(dataset,searchId,addtionObject){
let ind = dataset.findIndex(({id}) => id == searchId);
dataset[ind] = {...dataset[ind],...addtionObject}; //join the new and old array
return dataset
}
console.log(update(data,456,{status:1}))
If you want to create new state objet, you can use immer for that.
Immer will produce the nextState based on the mutations to the draft state.
import produce from "immer";
const baseState = [
{
id: 123,
name: "abc",
},
{
id: 456,
name: "bcd",
},
];
const nextState = produce(baseState, (draftState) => {
draftState[1].status = 1;
});

Get property of a grouped result from reduce in javascript

In grouped result I need the property of vendor and store in new array. but the give me some error. the error is Error: words is not defined.
how can I get vendor property from grouped list?
it is about to get result and store in new property.
const cart = {
"_id": 2,
"owner": 7,
"products": [{
"_id": {
"$oid": "5f06f9a4b8b878050fbc54b2"
},
"product": 1,
"vendor": 1,
"quantity": 2
}, {
"_id": {
"$oid": "5f06f9a4b8b878050fbc54b3"
},
"product": 2,
"vendor": 1,
"quantity": 1
}, {
"_id": {
"$oid": "5f06f9a4b8b878050fbc54b4"
},
"product": 4,
"vendor": 2,
"quantity": 1
}],
"createdAt": {
"$date": "2020-06-21T06:46:40.111Z"
},
"updatedAt": {
"$date": "2020-07-09T11:04:04.459Z"
},
"__v": 0,
"totalPrice": 265
}
const product = cart.products;
var grouped = product.reduce((dictionary, p) => {
dictionary[p.vendor] = dictionary[p.vendor] || [];
dictionary[p.vendor].push(p);
return dictionary;
}, {})
for (const p in grouped) {
console.log(grouped[p].vendor)
}
const cart = {
_id: 2,
owner: 7,
products: [
{
_id: {
$oid: "5f06f9a4b8b878050fbc54b2",
},
product: 1,
vendor: 1,
quantity: 2,
},
{
_id: {
$oid: "5f06f9a4b8b878050fbc54b3",
},
product: 2,
vendor: 1,
quantity: 1,
},
{
_id: {
$oid: "5f06f9a4b8b878050fbc54b4",
},
product: 4,
vendor: 2,
quantity: 1,
},
],
createdAt: {
$date: "2020-06-21T06:46:40.111Z",
},
updatedAt: {
$date: "2020-07-09T11:04:04.459Z",
},
__v: 0,
totalPrice: 265,
};
// const result = words.filter((word) => word.length > 6); // useless line, you do not have variable 'words'
const f = cart.products.filter((p) => p.vendor == 1);
const products = cart.products; //better variable naming
var grouped = products.reduce((dictionary, p) => {
dictionary[p.vendor] = dictionary[p.vendor] || [];
dictionary[p.vendor].push(p);
return dictionary;
}, {});
for (const p in grouped) {
console.log(grouped[p]); //is array
}
To fix this code just delete the line where you use variable words coz you didn't declare such.
To get vendor value:
grouped[p] is an array. It doesn't have a property vendor. But you can get it with:
for (const p in grouped) {
console.log(grouped[p][0].vendor);
}
or get an array of them:
let vendors = Object.getOwnPropertyNames(grouped);
Aside from the 2 lines of code which do nothing, I think you're trying to get the id of the vendor for each group - in which case this is just p in your code at the bottom which logs:
const cart = {"_id":2,"owner":7,"products":[{"_id":{"$oid":"5f06f9a4b8b878050fbc54b2"},"product":1,"vendor":1,"quantity":2},{"_id":{"$oid":"5f06f9a4b8b878050fbc54b3"},"product":2,"vendor":1,"quantity":1},{"_id":{"$oid":"5f06f9a4b8b878050fbc54b4"},"product":4,"vendor":2,"quantity":1}],"createdAt":{"$date":"2020-06-21T06:46:40.111Z"},"updatedAt":{"$date":"2020-07-09T11:04:04.459Z"},"__v":0,"totalPrice":265}
//const result = words.filter(word => word.length > 6);
//const f = cart.products.filter(p => p.vendor == 1);
const product = cart.products;
var grouped = product.reduce((dictionary, p) => {
dictionary[p.vendor] = dictionary[p.vendor] || [];
dictionary[p.vendor].push(p);
return dictionary;
}, {})
let vendor;
for (const p in grouped) {
console.log("vendor=", p, " count of items=", grouped[p].length)
}
I think this will give you the result you are looking for:
let f = cart.products.map( p => p.vendor);
let newArray = f.filter((vendor,index,arr)=>vendor!==arr[index+1]);
newArray.forEach(element => {
console.log(element);
});
You have some extraneous code in your script.
const result = words.filter(word => word.length > 6);
On line 36 you write const result = words.filter(word => word.length > 6); but words is not defined anywhere in your code and that is what generates the error.
For what concerns what you want to achieve, I am not entirely sure I understood it but, if I did, you can solve your issue like this:
const cart = {
"_id": 2,
"owner": 7,
"products": [{
"_id": {
"$oid": "5f06f9a4b8b878050fbc54b2"
},
"product": 1,
"vendor": 1,
"quantity": 2
}, {
"_id": {
"$oid": "5f06f9a4b8b878050fbc54b3"
},
"product": 2,
"vendor": 1,
"quantity": 1
}, {
"_id": {
"$oid": "5f06f9a4b8b878050fbc54b4"
},
"product": 4,
"vendor": 2,
"quantity": 1
}],
"createdAt": {
"$date": "2020-06-21T06:46:40.111Z"
},
"updatedAt": {
"$date": "2020-07-09T11:04:04.459Z"
},
"__v": 0,
"totalPrice": 265
}
const products = cart.products;
const vendors = products
.map(product => product.vendor)
.reduce((vendors, vendor) => {
if (vendors.indexOf(vendor) < 0) {
vendors.push(vendor);
}
return vendors;
}, []);
const productsByVendor = products.reduce((dictionary, p) => {
dictionary[p.vendor] = dictionary[p.vendor] || [];
dictionary[p.vendor].push(p);
return dictionary;
}, {});
console.log('Products grouped by vendor:\n', productsByVendor);
// in 'productsByVendor' the vendors are the keys of your object
console.log('Vendors:', Object.keys(productsByVendor));
/* if you want to retrieve the vendor of a specific product from 'productsByVendor'
* Assumptions:
* 1. cart.products[n].product is assumed to be a unique id (if that is not the case, you can use cart.products[n]._id instead)
* 2. I am assuming that each product can be sold by only one vendor; if a product can be sold by more than one vendor you'll have to adjust a bit the function
*/
getVendorIdFromGroupedProducts = (productId) => {
for (let key of Object.keys(productsByVendor)) {
for (let prod of productsByVendor[key]) {
if (prod.product === productId) {
return prod.vendor
}
}
}
return 'The product does not exist'
};
console.log('Vendor of product 1 is:', getVendorIdFromGroupedProducts(1));
console.log('Vendor of product 2 is:', getVendorIdFromGroupedProducts(2));
console.log('Vendor of product 3 is:', getVendorIdFromGroupedProducts(3));
console.log('Vendor of product 4 is:', getVendorIdFromGroupedProducts(4));

get the name of the key that has the highest property value in nested javascript objects, [duplicate]

This question already has answers here:
Get object keys with the highest value in Javascript
(4 answers)
Closed 3 years ago.
var food = {
"fruit":{"brand":{"grgrdgdr":true,"ggyugy":true}, "sold":2},
"vegetable" :{"brand":{"htrhtr":true},"sold": 1},
"snack":{"brand":{"htrhr":true},"sold": 3},
"other":{"brand":{"gdhshd":true},"sold":1},
....
...
...
};
How do I console log the object name that sold the most,
in this case should be the word snack.
I find this link, but its structure is not similar to mine.
Get object keys with the highest value in Javascript
any help is appreciated
thanks in advance
You could sort by the values property and get the first item.
var food = { fruit: { brand: { grgrdgdr: true, ggyugy: true }, sold: 2 }, vegetable: { brand: { htrhtr: true }, sold: 1 }, snack: { brand: { htrhr: true }, sold: 3 }, other: { brand: { gdhshd: true }, sold: 1 } };
result = Object
.keys(food)
.sort((a, b) => food[b].sold - food[a].sold)
[0];
console.log(result);
Find the max value first, and then filter the object to get objects having max sold value
var food = {
"fruit":{"brand":{"grgrdgdr":true,"ggyugy":true}, "sold":2},
"vegetable" :{"brand":{"htrhtr":true},"sold": 1},
"snack":{"brand":{"htrhr":true},"sold": 3},
"other":{"brand":{"gdhshd":true},"sold":1}}
var maxSold = Math.max(...Object.values(food).map(o=> o.sold))
var result = Object.keys(food).filter(o => food[o].sold ===maxSold)
console.log(result) //this will given all objects with max sold value
You can use a variable & iterate the array twice. In the first iteration get the highest sold. Then on second iteration add the products whose sold value is same as the highest sold
var food = {
"fruit": {
"brand": {
"grgrdgdr": true,
"ggyugy": true
},
"sold": 5
},
"vegetable": {
"brand": {
"htrhtr": true
},
"sold": 1
},
"snack": {
"brand": {
"htrhr": true
},
"sold": 3
},
"other": {
"brand": {
"gdhshd": true
},
"sold": 1
},
"someOtherfruit": {
"brand": {
"grgrdgdr": true,
"ggyugy": true
},
"sold": 5
}
}
let highestSold = 0;
let newObj = [];
for (let keys in food) {
if (food[keys].sold > highestSold) {
highestSold = food[keys].sold
}
}
for (let keys in food) {
if (food[keys].sold === highestSold) {
newObj.push(food[keys])
}
}
console.log(newObj[0])
var food = {
"fruit":{"brand":{"grgrdgdr":true,"ggyugy":true}, "sold":2},
"vegetable" :{"brand":{"htrhtr":true},"sold": 1},
"snack":{"brand":{"htrhr":true},"sold": 3},
"other":{"brand":{"gdhshd":true},"sold":1},
};
function getMostExpensivesKey(array) {
let key = Object.keys(array)[0];
Object.keys(array).forEach(function(k) {
if(array[k].sold > array[key].sold) {
key = k;
}
});
return key;
}
console.log(getMostExpensivesKey(food));
Your posted link Get object keys with the highest value in Javascript
was quite close
var food = {
"fruit":{"brand":{"grgrdgdr":true,"ggyugy":true}, "sold":2},
"vegetable" :{"brand":{"htrhtr":true},"sold": 1},
"snack":{"brand":{"htrhr":true},"sold": 3},
"other":{"brand":{"gdhshd":true},"sold":1}
},
result = Object
.keys(food)
.sort(function(a, b) {
return food[b].sold - food[a].sold;
})[0] // or .slice(0, 1);
console.log(result,food[result]);
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}

How to remove complete unique value from array [duplicate]

This question already has answers here:
How to remove all duplicates from an array of objects?
(77 answers)
Closed 3 years ago.
How to remove complete record of same object in array please help me this, I am using below funtion but its only remove one value I want remove complete object of same object
var data = [{
"QuestionOid": 1,
"name": "hello",
"label": "world"
}, {
"QuestionOid": 2,
"name": "abc",
"label": "xyz"
}, {
"QuestionOid": 1,
"name": "hello",
"label": "world"
}];
function removeDumplicateValue(myArray) {
var newArray = [];
$.each(myArray, function (key, value) {
var exists = false;
$.each(newArray, function (k, val2) {
if (value.QuestionOid == val2.QuestionOid) { exists = true };
});
if (exists == false && value.QuestionOid != undefined) { newArray.push(value); }
});
return newArray;
}
I want result like this
[{
"QuestionOid": 2,
"name": "abc",
"label": "xyz"
}]
You can use reduce.
var data = [{"QuestionOid": 1,"name": "hello","label": "world"}, {"QuestionOid": 2,"name": "abc","label": "xyz"}, {"QuestionOid": 1,"name": "hello","label": "world"}];
let op = data.reduce((op,inp)=>{
if(op[inp.QuestionOid]){
op[inp.QuestionOid].count++
} else {
op[inp.QuestionOid] = {...inp,count:1}
}
return op
},{})
let final = Object.values(op).reduce((op,{count,...rest})=>{
if(count === 1){
op.push(rest)
}
return op
},[])
console.log(final)
Do with Array#filter.Filter the array matching QuestionOid value equal to 1
var data = [{ "QuestionOid": 1, "name": "hello", "label": "world" }, { "QuestionOid": 2, "name": "abc", "label": "xyz" }, { "QuestionOid": 1, "name": "hello", "label": "world" }]
var res = data.filter((a, b, c) => c.map(i => i.QuestionOid).filter(i => i == a.QuestionOid).length == 1)
console.log(res)

Filter array of objects by multiple properties and values

Is it possible to filter an array of objects by multiple values?
E.g in the sample below can I filter it by the term_ids 5 and 6 and type car at the same time?
[
{
"id":1,
"term_id":5,
"type":"car"
},
{
"id":2,
"term_id":3,
"type":"bike"
},
{
"id":3,
"term_id":6,
"type":"car"
}
]
Definitely up for using a library if it makes it easier.
You can do it with Array.filter
var data = [{
"id": 1,
"term_id": 5,
"type": "car"
},
{
"id": 2,
"term_id": 3,
"type": "bike"
},
{
"id": 3,
"term_id": 6,
"type": "car"
}
];
var result = data.filter(function(v, i) {
return ((v["term_id"] == 5 || v["term_id"] == 6) && v.type == "car");
})
console.log(result)
The following function will help you out.
nestedFilter = (targetArray, filters) => {
var filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
return filterKeys.every(function (eachKey) {
if (!filters[eachKey].length) {
return true;
}
return filters[eachKey].includes(eachObj[eachKey]);
});
});
};
Use this function with filters described as below:
var filters = {
"id": ["3"],
"term_id": ["6"],
"type": ["car","bike"]
}
Dont pass empty array. If there are no values in the array, skip that property in the filters.
The result will be filtered array.
You can do this with plain js filter() method and use && to test for both conditions.
var data = [{"id":1,"term_id":5,"type":"car"},{"id":2,"term_id":3,"type":"bike"},{"id":3,"term_id":6,"type":"car"}];
var result = data.filter(function(e) {
return [5, 6].includes(e.term_id) && e.type == 'car'
});
console.log(result);
Another way to do it is to use lodash filter + reduce.
const arr = [{"id":1,"term_id":5,"type":"car"},{"id":2,"term_id":3,"type":"bike"},{"id":3,"term_id":6,"type":"car"}];
const result = [
{term_id: 5, type: 'car'},
{term_id: 6, type: 'car'},
].reduce((prev, orCondition) => prev.concat(_.filter(arr, orCondition)), []);
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>

Categories