Check if my string contains elements from array - javascript

I have an array of objects and I wish to filter out those objects if my filter array matches the string of a key.
// my stores
var stores = [
{
id: 1,
store: 'Store 1',
storeSells: "Belts|Handbags|Watches|Wallets"
},
{
id: 2,
store: 'Store 2',
storeSells: "Handbags|Personal Accessories|Jewelry|Eyewear|"
},
{
id: 3,
store: 'Store 3',
storeSells: "Belts|Travel|Charms|Footwear|"
},
{
id: 4,
store: 'Store 3',
storeSells: "Charms|Footwear|"
}
]
// my filters
var filters = ["Handbags","Belts"]
So, If my filters array has handbags and belts. I wish to filter stores with id's 1,2 and 3 only as they contains these keywords. Can you please help me with this?

You can try with Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Array.prototype.some()
The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
And String.prototype.includes()
The includes() method determines whether one string may be found within another string, returning true or false as appropriate.
// my stores
var stores = [
{
id: 1,
store: 'Store 1',
storeSells: "Belts|Handbags|Watches|Wallets"
},
{
id: 2,
store: 'Store 2',
storeSells: "Handbags|Personal Accessories|Jewelry|Eyewear|"
},
{
id: 3,
store: 'Store 3',
storeSells: "Belts|Travel|Charms|Footwear|"
},
{
id: 4,
store: 'Store 3',
storeSells: "Charms|Footwear|"
}
]
// my filters
var filters = ["Handbags","Belts"];
var res = stores.filter(item => filters.some(i=>item.storeSells.includes(i)));
console.log(res);

Related

Creating a function that compares 2 different arrays and passs down each matching pair into a component

I am trying to create a component that calls upon two arrays. The arrays are them mapped out and the pair that matches is send down through props into a child component. I am making a list component that calls said arrays from the back end and then sends down the information to a listItem component to be rendered. The arrays look something like this
const Stores = [
{
id: 1,
name: Store One,
},
{
id: 2,
name: Store Two,
},
]
const Users = [
{
id: 100,
name: User One,
storeId: 1,
},
{
id: 200,
name: User Two,
storeId: 1,
},
{
id: 300,
name: User Three,
storeId: 2,
},
{
id: 400,
name: User Four,
storeId: 2,
},
]
Currently i am just passing down the user information into the listItem component and using http requests on each item but as you can tell when the User or Stores list reaches 100+ items that the amount of http requests will bog down the app too much. What I thought of is just calling once in the List component and passing down each information that way it would be one call but cannot figure out the function required to acheive this. Is there anyone that can help me brainstorm?
const Stores = [{
id: 1,
name: 'Store One',
},
{
id: 2,
name: 'Store Two',
},
]
const Users = [{
id: 100,
name: 'User One',
storeId: 1,
},
{
id: 200,
name: 'User Two',
storeId: 1,
},
{
id: 300,
name: 'User Three',
storeId: 2,
},
{
id: 400,
name: 'User Four',
storeId: 2,
},
]
const grouped = Users.map(user => {
// find store
const store = Stores.find(store => store.id === user.storeId)
// return grouped
return {
user: { ...user },
store: { ...store }
}
})
console.log(grouped)

JAVASCRIPT - Get Value from Parent Array of Objects, inside the Child Object after Array Flattening

I have an Array of Objects, which has some values. Examples:
bigArray: [
{
greatName: 'Name String - #1',
array: [{
id: 1,
name: 'string name - #1'
}]
},
{
greatName: 'Name String - #2',
array: [{
id: 2,
name: 'string name - #2'
}]
},
{
greatName: 'Name String - #3',
array: [{
id: 3,
name: 'string name - #3'
}]
}
]
I used the following composed functions from ramda, in order to get all Arrays array properties value and flatten them into a single array:
const extractRB = compose(
flatten,
map(props(['array']))
);
Which gave me back the following array:
// Flatten Array:
flatten: [
{
id: 1,
name: 'string name - #1'
},
{
id: 2,
name: 'string name - #2'
},
{
id: 3,
name: 'string name - #3'
}
]
Now, that is a requirement, for my feature. THE PROBLEM is I also need the greatName, property value inside each object, in order to map through them. But I cannot find a way to actually get the correct values inside the object..
What I want to achieve is this Array of Objects. Keep in mind that I can have dozens of Objects in Big Array, and hundrends of Objects inside each child array:
// Flatten Array:
flatten: [
{
id: 1,
name: 'string name - #1'
greatName: 'Name String - #1',
},
{
id: 2,
name: 'string name - #2',
greatName: 'Name String - #2',
},
{
id: 3,
name: 'string name - #3',
greatName: 'Name String - #3',
}
]
I did this, which is spreading the original object from the flatten array and add the greatName property to it, but how to calculate which is the correct value for each object. There is no common value between the object and the array to condition on:
flatten.map(flatObj => {...flatObj, greatName: bigArray.map(// what operation can I do here, to get the correct value for each object inside the `bigArray` )});
I tried quite a few conditional operation, but they will always return false. Mayne there is a way to do it with the length of each array but not sure how to do it.
Help would be greatly appreciated..!! Thank you!!
var bigArray= [
{
greatName: 'Name String - #1',
array: [{
id: 1,
name: 'string name - #1'
}]
},
{
greatName: 'Name String - #2',
array: [{
id: 2,
name: 'string name - #2'
}]
},
{
greatName: 'Name String - #3',
array: [{
id: 3,
name: 'string name - #3'
}]
}
]
console.log(bigArray.flatMap(({greatName, array}) => array.flatMap(x => ({greatName, ...x}))))
If array property always have only 1 element, so you can write it shorter:
bigArray.map(({greatName, array}) => ({greatName, ...array[0]}))
Can you try this once, may be this will solve your problem:
bigArray.forEach((item)=>{
item.array.greatName = item.greatName;
delete item.greatName;
})
Just console bigArray and don't use this and just try with above method
const extractRB = compose(
flatten,
map(props(['array']))
);

Order objects in array based on values of two attributes

I have an array of N objects and each object has the following fields:
{
id: 'an id',
description: 'a description',
isUser: true/false
}
I need to order that array based on two things:
Firstly, if the description includes either 'dog', 'cat' or 'animal', it should have sooner position in the array.
Secondly, if the value isUser is false, it should also have a sooner position in the array.
I have notice that the sort function doesn't help when you want to prioritize by value of different attributes, so I am wondering what is the best way to do this in Javascript (or Lodash, which I am also using: https://lodash.com/)
You could check if the wanted top string are in the description and move these item to top, as well as false values of isUser.
var array = [{ id: 1, description: 'cat', isUser: false }, { id: 5, description: 'dog', isUser: true }, { id: 6, description: 'flower', isUser: true }, { id: 7, description: 'cat', isUser: true }, { id: 2, description: 'animal', isUser: false }, { id: 3, description: 'tree', isUser: false }, { id: 4, description: 'dog', isUser: false }];
array.sort(function (a, b) {
var top = ['dog', 'cat', 'animal'];
return top.includes(b.description) - top.includes(a.description) || a.isUser - b.isUser;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var test = [{
id: 'an id',
description: 'a description dog',
isUser: false
},{
id: 'an id 2',
description: 'a description animal',
isUser: true
},{
id: 'an id 3',
description: 'a description',
isUser: true
},{
id: 'an id 4',
description: 'a description',
isUser: false
}]
function sort(arr){
return arr.sort(a=> !(a.description.includes('dog')||a.description.includes('cat')||a.description.includes('animal') || !a.isUser))
}
console.log(sort(test))
Assuming you question is to rearrange the existing array based on the properties and conditions given.
// grouping on basis of "description"
const animalGrp = _.groupBy(array, (t) => _.includes(t.description, 'dog') || _.includes(t.description, 'cat') || _.includes(t.description, 'animal') );
// grouping on basis of "isUser"
const userGrp = _.groupBy(animalGrp.false, 'isUser');
// final output
const result = [...animalGrp.true, ...userGrp.true, ...userGrp.false]
You can pass a compareFunction to sort method of array, so the sort function should help. Example:
yourArray.sort( function(a, b) {
if ( !a.isUser || a.description == 'animal') return -1;
return 1;
});

EXTJS Grid grouping by Object error

I am trying to implement a grid with grouping feature. This is my Model:
Model
Ext.define('myApp.model.ModelPrueba2', {
extend: 'Ext.data.Model',
fields: ['id', {
name: 'name',
type: 'string'
},'sign']
});
I fill my store from an AJAX proxy request. This is my JSON:
{
success: true,
data: [{
id: 1,
name: 'Name 1',
sign: {
id: 1,
name: 'F1'
}
}, {
id: 2,
name: 'Name 2',
sign: {
id: 2,
name: 'F2'
}
}]
}
You can appreciate that my 'sign' field is an 'object'. My problem is: when I group by 'name', it works fine, and if I collapse some group, it only collapses the group that I selected. However, if I group by 'sign', the groups are well-formed and displayed, but when I collapse a specific group, all the groups get collapsed, and the only difference with the previous test is the field type, 'name' is string and 'sign' is an object... So I don't really know if this a bug. I am using 4.2 version.
This is a fiddle where you can test my problem: https://fiddle.sencha.com/#fiddle/vt
Here you can group by 'probabilities to win', and collapse one group, it works fine, but if you delete every
toString: function() {
return this.value;
}
from the 'data' array and do the same, you will see how all groups get collapsed in one. What can I do to fix this?, I don't like to use this toString() in my store or JSON.
How can I group by an Object attribute?
you MAY have some luck with a "hasOne" relationship in your model instead of the "auto' type. (I'm not sure if it's possible to group using a relationship)
Or you could create another field just for the grouping (type string or int) like this :
{
success: true,
data: [{
id: 1,
name: 'Name 1',
myGroupField : 1,
sign: {
id: 1,
name: 'F1'
}
}, {
id: 2,
name: 'Name 2',
myGroupField : 2,
sign: {
id: 2,
name: 'F2'
}
}]
}
A similar solution is to bring up the field from your nested object to the parent object :
{
success: true,
data: [{
id: 1,
name: 'Name 1',
signId: 1,
signName: 'F1'
}, {
id: 2,
name: 'Name 2',
signId: 2,
signName: 'F2'
}]
}
and then group by signId

AngularJS disable 2 way binding

This actually might be a JavaScript question, but it is happening when I am using AngularJs.
Say I have an array like this:
var players = [
{
id: 1,
name: 'Player 1'
},
{
id: 2,
name: 'Player 2'
}
];
and then I have another array like this:
var teams = [
{
id: 1,
name: 'Team 1',
members: players
},
{
id: 2,
name: 'Team 2',
members: players
}
];
If I decide to add a new property called position to one of the teams:
teams[0].members[0].position = 1;
I don't want it to then update the second team members position.
I hope that makes sense.
Here is a codepen to illustrate my issue:
http://codepen.io/r3plica/pen/ZGZXjb?editors=101
Array in java-script are mutable so you need to make copy of player and assign it to teams member property.
Just change your code to :
var teams = [
{
id: 1,
name: 'Team 1',
members: angular.copy(players)
},
{
id: 2,
name: 'Team 2',
members: angular.copy(players)
}
];
for more information see : https://docs.angularjs.org/api/ng/function/angular.copy
The only way (if both teams have the same players) is to use a copy of the array for the second team. Now it's logical the second team gets updated, because both teams point to the same reference of players.
You can use angular.copy for that.
var copyofplayers = [];
angular.copy(players, copyofplayers);
also can use jQuery.extend() like
var teams = [
{
id: 1,
name: 'Team 1',
members: jQuery.extend({}, players)
},
{
id: 2,
name: 'Team 2',
members: jQuery.extend({}, players)
}
];

Categories

Resources