Hey I created my first app in react native and i run into some trouble, i simple would like to know how i can check an object for an specific value from a local storage. This is what i have so far, i know its not that much.
handleClick = (item)=>{
store.get('myobject').then((res) =>
console.log(res)
)
this is my res object:
[
{ id: '456', p: 'hey' },
{ id: '464', p: 'ho' },
{ id: '467', p: 'lets' },
{ id: '263', p: 'go' }
]
and as example i would like to know, if id 467 is in the object.
You could make use of the some method of Array:
var res = [
{ id: '456', p: 'hey' },
{ id: '464', p: 'ho' },
{ id: '467', p: 'lets' },
{ id: '263', p: 'go' }
];
var found = res.some(item => item.id === '467');
console.log(found);
Essentially, as it is stated here
The some() method tests whether at-least one element in the array
passes the test implemented by the provided function.
You could do a forEach loop and check for your desired value:
var res = [
{ id: '456', p: 'hey' },
{ id: '464', p: 'ho' },
{ id: '467', p: 'lets' },
{ id: '263', p: 'go' }
]
function containsCheck(array) {
var found = false;
array.forEach(function(element) {
if (element.id === '467') {
found = true;
}
});
return found;
};
console.log(containsCheck(res));
As an alternative you can check Lodash This lib is a nice thing to have in a project when working with collections or objects.
Related
My data:
[{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
I want to do something like this:
[
{
name: "foo",
id: 1,
count: 2
},
{
name: "bar",
id: 2,
count: 1
}
]
Now i'm grouping the elements with groupBy by name.
Thanks for the help!
var source = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
var result = _(source)
.groupBy('name')
.map(function(items, name) {
return {
name: name,
count: items.length
}
}).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
It's not exactly what you asked for, but here is a simple method without using lodash. Here I'm using the ID of each element, but you can use anything that uniquely identifies it.
const objArray = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
const reduceAndCount = (arr) => {
const newMap = {};
arr.forEach(el => {
if (!newMap[el.id]) {
el.count = 1
return newMap[el.id] = el
}
newMap[el.id].count = newMap[el.id].count + 1
})
return Object.values(newMap)
}
const result = reduceAndCount(objArray)
console.log(result)
With deference to the answer provided here which uses 'lodash', as requested in the above question, the below points are observed:
the 'groupBy' is fixed (ie, the 'name' field/column/prop) is used
the result given includes the name & count, but the expected result needs the 'id' as well.
EDIT:
Adding solution using lodash,
const arrayRaw = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}];
const groupBy = (col = 'name', arr = arrayRaw) => (
_(arr).groupBy(col).map(it => ({
...it[0],
count: it.length
})).value()
);
console.log(groupBy());
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>
In case, someone requires a solution without 'lodash', the below should be one possible implementation:
const arrayRaw = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}];
const groupBy = (col = 'name', arr = arrayRaw) => (
Object.entries(arr.reduce((fin, itm, idx) => ({
...fin,
[itm[col]]: (fin[itm[col]] || []).concat([idx])
}), {})).map(([k, v]) => ({
...arr[v[0]],
count: v.length
}))
);
console.log(groupBy());
Approach / Explanation
It is self-explanatory, however, should anyone require one - please comment and I shall add.
I'm using the assert syntax of chai for this.
I know that if I want to check an array of objects for a specific object, I can do this:
assert.deepInclude(
[
{ name: 'foo', id: 1 },
{ name: 'bar', id: 2 }
],
{ name: 'foo', id: 1 }
)
Which should pass.
But what if I only have 1 property in the object that I'm checking for...? Like this:
assert.deepInclude(
[
{ name: 'foo', id: 1 },
{ name: 'bar', id: 2 }
],
{ name: 'foo' }
)
I still want this to pass, but it's telling me it's failing because that exact object does not exist.
Using chai-subset this can be done pretty easily:
const chai = require('chai');
const chaiSubset = require('chai-subset');
chai.use(chaiSubset);
it('should contain subset', () => {
const actual = [
{ name: 'foo', id: 1 },
{ name: 'bar', id: 2 },
];
expect(actual).to.containSubset([{ name: 'foo' }]);
});
Afaik there's no way to do this with chai alone, but you could write your own function:
function containsPartialObj(arr, obj) {
return arr.some(entry => {
const keys = Object.keys(obj);
return keys.every(key => obj[key] === entry[key]);
});
}
it('should contain subset', () => {
const actual = [
{ name: 'foo', id: 1 },
{ name: 'bar', id: 2 },
];
expect(containsPartialObj(actual, { name: 'foo' })).to.be.true;
});
I have an array and I want to delete an object in it.
I only have the complete object and I want to delete from the array inside it.
Object = {Comments: [{text: 'hello', x:200, y:100},
{text: 'hi', x:565, y:454},
{text: 'Hola', x:454, y:235}
]
};
I want to delete this object :
toDelete = {text: 'hi', x:565, y:454}
How can I do this?
You can use
Object.Comments.splice(1, 1);
But you should also give your variable a different name and use let or var.
You can use filter to remove an item from an array:
const myArray = [
{ text: 'one', digit: 1 },
{ text: 'two', digit: 2 },
{ text: 'three', digit: 3 }
];
const filteredArray = myArray.filter(item => {
return item.text !== 'two' && item.digit !== 2
});
console.log(filteredArray); // [ { text: 'one', digit: 1 }, { text: 'three', digit: 3 } ]
You should use a unique id for comments array.
var Object = {
Comments: [{
id: 1,
text: 'hello',
x: 200,
y: 100
},
{
id: 2,
text: 'hi',
x: 565,
y: 454
},
{
id: 3,
text: 'Hola',
x: 454,
y: 235
}
]
};
const {
Comments
} = Object;
function deleteComment = (itemArray, id) => {
return itemArray.filter(itm => {
return itm.id !== id
})
}
const filterdArray = deleteComment(Comments, passYourTargetId);
// in this filterdArray you get without that item you want to remove and it work with immutable way
I'm using Lodash. I have the array below:
const array = [{id:1,name:a},{id:2,name:b},{id:3,name:c},{id:4,name:d},{id:5,name:e}];
and I'm about to add another object to this array but before that, I need to check if the new object's name is already in the array or not and if there is one with the name I won't add the new object anymore.
I know some ways to do it, for instance, a loop with _.map, but want to make sure if there is an easier way.
You could use Lodash's some which if provided with an appropriate predicate e.g. (item => item.name === newName) will return a boolean indicating whether or not the item already exists (in this case, true would mean the name already exists). The benefit of using this over other iterating methods is that it will stop as soon as it finds one that returns true resulting in better performance.
With native javascript , you can use findIndex, this will return the index of the object where the name matches. If it returns -1 then there is no such object with same name. In that case update the array.
const array = [{
id: 1,
name: 'a'
}, {
id: 2,
name: 'b'
}, {
id: 3,
name: 'c'
}, {
id: 4,
name: 'd'
}, {
id: 5,
name: 'e'
}];
let newObjToAdd = {
id: 1,
name: 'z'
};
let newObjNotToAdd = {
id: 1,
name: 'a'
}
function updateArray(obj) {
let k = array.findIndex((item) => {
return item.name === obj.name;
})
if (k === -1) {
array.push(obj)
} else {
console.log('Array contains object with this name')
}
}
updateArray(newObjToAdd);
console.log(array)
updateArray(newObjNotToAdd);
You don't need lodash for some. You get that with native JS too (ES6):
const array = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'},{id:4,name:'d'},{id:5,name:'e'}];
console.log(array.some(e => e.name === 'a'));
if (!array.some(e => e.name === 'z')) {
array.push({id: 5, name: 'z'});
}
console.log(array);
Doing this with lodash is few chars shorter but here is how you could do it with ES6 and Array.some:
const array = [{ id: 1, name: "A" }, { id: 2, name: "B" }, { id: 3, name: "C" }, { id: 4, name: "D" }, { id: 5, name: "C" }];
const maybeUpdate = (arr, obj) => {
if(!array.some(x => x.id == obj.id))
array.push(obj)
}
maybeUpdate(array, {id: 2, name: "F"}) // id exists wont insert
maybeUpdate(array, {id: 12, name: "F"}) // will insert
console.log(array)
Same idea with lodash and _.some would be:
const array = [{ id: 1, name: "A" }, { id: 2, name: "B" }, { id: 3, name: "C" }, { id: 4, name: "D" }, { id: 5, name: "C" }];
const maybeUpdate = (arr, obj) => {
if(!_.some(array, {id: obj.id}))
array.push(obj)
}
maybeUpdate(array, {id: 2, name: "F"}) // id exists wont insert
maybeUpdate(array, {id: 12, name: "F"}) // will insert
console.log(array)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Note that you could also use various other ways to get the same result. Array.find or _.find would work as well since all you have to do is to check if there was a hit:
const maybeUpdate = (arr, obj) => {
if(!_.find(array, {id: obj.id})) // or if(!array.find(x => x.id == obj.id))
array.push(obj)
}
I'm developing with Angular and I have the following Typescript array of objects:
docs = [
{
id: '1',
type: {
id: 1
desc: 'Category 1',
}
title: 'Foo",
date: '2018-06-21',
attachments: [
{ id: 51, filename: 'foo.pdf', title: 'Foo' },
{ id: 20, filename: 'bar.doc', title: 'Bar' }
]
},
{
id: '2',
type: {
id: 2
desc: 'Category 2',
}
title: 'Bar",
date: '2018-06-21',
attachments: [
{ id: 15, filename: 'foobar.xls', title: 'Foobar' },
{ id: 201, filename: 'example.doc', title: 'Example' }
]
}
]
I need to get only a subset of the properties, something like this:
docs = [
{
id: '1',
type: {
id: 1
desc: 'Category 1',
}
attachments: [
{ id: 51 },
{ id: 20 }
]
},
{
id: '2',
type: {
id: 2
desc: 'Category 2',
}
attachments: [
{ id: 15 },
{ id: 201 }
]
}
]
How can I achieve this?
Have I to create a parser or does exist any smart way (such as Lodash) to extract a lite version of the array?
var docs = [{"id":"1","type":{"id":1,"desc":"Category 1"},"title":"Foo","date":"2018-06-21","attachments":[{"id":51,"filename":"foo.pdf","title":"Foo"},{"id":20,"filename":"bar.doc","title":"Bar"}]},{"id":"2","type":{"id":2,"desc":"Category 2"},"title":"Bar","date":"2018-06-21","attachments":[{"id":15,"filename":"foobar.xls","title":"Foobar"},{"id":201,"filename":"example.doc","title":"Example"}]}];
const result = docs.map(({id,type,attachments})=>{
let doc={id,type};
doc.attachments=attachments.map(({id})=>({id}));
return doc;
});
console.log(result);
have a look at this. this works perfectly!
You can use array.map and object destructuring to extract only the wanted properties.
Also use JSON.parse and JSON.stringify to make a copy and avoid side effetcs.
docs2 = JSON.parse(JSON.stringify(docs)).map(
({id, type, attachements}) =>
({ id,
type,
attachements: attachements.map(({id}) => ({id})
})
)
You can use Array.map with object spreading, something like this:
const mapSubset = ({ id, type, attachments }) => {
return { id, type, attachments: attachments.map( {id} => id ) };
};
const subset = docs.map( mapSubset );
I was looking for a non-specific way to accomplish this or any other similar cases, so far I've thought of the following:
Have an IMapping<T> type, that defines the way to map each property.
Have an IMappingFunction<T> interface, that determines how to map a specific thing:
The following code demonstrates it:
type IMapping<T> = {
[P in keyof T]: IMapping<T[P]> | IMappingFunction<T[P]>;
}
interface IMappingFunction<T>{
(t: T): T | Partial<T>
}
class Person{
name: string;
lastName: string;
}
const obj: IMapping<Person> = {
name: s => s.toUpperCase(),
lastName: s => s
}
function map<T>(obj: T, mapping: IMapping<T>) {
return Object.keys(obj)
.map(prop => {
const propMapping = mapping[prop];
return {
key: prop,
value: typeof propMapping === 'function' ?
propMapping(obj[prop]) :
map(obj, propMapping)
};
})
.reduce((acc, prop) => ({...acc, [prop.key]: prop.value}), { });
}
console.log(map({ name: 'Name', lastName: 'LastName'}, obj));
For a runnable snippet check here
do you need to leave the original array intact? If not you can iterate through the list of objects using a for loop and use the 'delete' operator to delete the properties you no longer want.
For example:
var Employee = {
firstname: "Mohammed",
lastname: "Haddad"
}
delete Employee.firstname;
console.log(Employee);
// expected output: { lastname: "Haddad" }