Test whether value exists within array of objects - javascript

I have an array of objects and I would like to test it to determine whether a property with a certain value exists (at least one occurrence) and for it to return a boolean value to indicate the result. I'm using the Ramda library and have been experimenting with the has function to try and achieve this, however this only returns a boolean on whether the actual property exists and not it's respective value.
const data = [
{
id: 10004,
name: 'Daniel',
age: 43,
sport: 'football'
},
{
id: 10005,
name: 'Tom',
age: 23,
sport: 'rugby'
},
{
id: 10006,
name: 'Lewis',
age: 32,
sport: 'football'
},
];
Checking the array of objects for sport: 'rugby' should return true and sport: 'tennis' should return false.
Any help will be greatly appreciated, thanks.

If you're looking for a Ramda solution, this would do fine:
R.filter(R.propEq('sport', 'rugby'))(data)
R.has, as you noted, just checks whether an object has the named property. R.propIs checks whether the property is of the given type. R.propEq tests whether the property exists and equals a given value, and the more generic R.propSatisfies checks whether the property value matches an arbitrary predicate.

You can try this function:
function myFind(data, key, value) {
return data.some(function(obj){
return key in obj && obj[key] == value;
});
}
Reference: Array.some()

Related

Remove element from objects in javascript multidimensional array

I have read several solutions to this problem here. When I try it, I continue to receive an error for the pop() method.
I have what is essentially a multidimensional array in javascript.
I am tasked with returning the array with the sensitive info removed (e.g. remove the SSN, in this example)
I thought I could use a foreach loop, and the pop() function to remove the last element of the child arrays, the SSN.
testing it using node on the commandline, the stdout is telling me that element.pop() is not a function. i've tried it with pop(), slice(), filter(), all with no success.
when running $> node filename.js
H:\Apache2\htdocs\test\filename.js:50
noppi[i] = element.pop();
^
TypeError: element.pop is not a function
let recs = [
{
ID: 1,
NAME: 'John',
EMAIL: 'john#example.com',
SSN: '123'
}, {
ID: 2,
NAME: 'Sally',
EMAIL: 'sally#example.com',
SSN: '456'
}, {
ID: 3,
NAME: 'Angie',
EMAIL: 'angie#example.com',
SSN: '789'
}
];
let i = 0;
let noppi = [];
recs.forEach(element => {
noppi[i] = element.pop();
i++;
});
console.log(noppi);
At the risk of sounding redundant, I'll briefly reiterate what the earlier answers have already stated.
The input data structure isn't a multi-dimensional array [ [ ... ], [ ... ] ] , it's an array of objects [ {...}, {...} ]. So you can't use Array methods like .pop() on the objects {...}.
Here's a simple one-liner that uses .forEach() and delete.
recs.forEach(obj => delete obj.SSN)
delete is an operator with one purpose: to remove an object's property like for example SSN: '123-45-6789'. Simple and perfect.
Note, .forEach() mutates the array, meaning that it's the original data being changed (see Minja's comment).
let recs = [
{
ID: 1,
NAME: 'John',
EMAIL: 'john#example.com',
SSN: '123'
}, {
ID: 2,
NAME: 'Sally',
EMAIL: 'sally#example.com',
SSN: '456'
}, {
ID: 3,
NAME: 'Angie',
EMAIL: 'angie#example.com',
SSN: '789'
}
];
recs.forEach(obj => delete obj.SSN);
console.log(recs)
Try this:
recs.forEach(element => {
noppi.push = element;
});
You are trying to use pop() on an object not an array
As per your need you need to remove SSN from your object, try below code it should work for you.
recs.forEach(element => {
const { SSN, ...rest } = element;
noppi.push(rest);
});
Here we are removing SSN from object and rest will push in noppi.

Lodash merge object with nested array not working correctly

I found unexpected result when try to merge with lodash object with flat array inside.
Here the example:
var people = { name: 'Andrew', age: '30', values: ["PT", "PORTA 31"] };
const person = { age: '31', values: ["PT"] };
var people2 = { name: 'Andrew', age: '30', values: [{ pippo : 1}] };
const person2 = { age: '31', values: [{ pippo : 2}] };
// Now merge person back into people array
console.log(_.merge({}, people, person));
console.log(_.merge({}, people2, person2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
The result of first console.log is
{
age: "31",
name: "Andrew",
values: ["PT", "PORTA 31"]
}
And not as expected
{
age: "31",
name: "Andrew",
values: ["PT"]
}
Someone can explain me why and give me a solution to make sure that with a flat array it takes me the correct value
I think assign is better in this case than merge
This method is like _.assign except that it recursively merges own and inherited enumerable string keyed properties of source objects into the destination object. Source properties that resolve to undefined are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
var people = { name: 'Andrew', age: '30', values: ["PT", "PORTA 31"] };
const person = { age: '31', values: ["PT"] };
console.log(_.assign({}, people, person));
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.20/lodash.min.js"></script>
I believe _.assign(people, person) would produce the desired outcome in this case https://lodash.com/docs/4.17.15#assign
This functionality is also native and can be used like this Object.assign(target, source)

Javascript Property with three dots (...)

I have a problem with code I am supposed to work with. I found a syntax I am not familiar with and I have trouble googling the documentation:
export const Something = class Something {
constructor(someObject = {}) {
this.someObject = {...Something.someObjectDefaultAsStaticMethod,...someThing};
};
// The rest of the class
};
I have problems understanding what the three dots (...) in front of the parameter do. And "dots in parameter javascript" is a bad search term. Can someone help me, maybe tell me what this syntax is actually called or just directly link me to documentation?
That is not ES6 but has only been added in ECMAScript 2018.
It is called "Object Rest/Spread Properties" and is part of the Spread Syntax.
... (three dots in Javascript) is called the Spread Syntax or Spread Operator. This allows an iterable such as an array expression or string to be expanded or an object expression to be expanded wherever placed.
I want to list down the mostly used practical Use Cases of the Spread Syntax (Spread Operator). The following has been explained with examples in this stackoverflow answer.
Combine Arrays (Concatenate Arrays)
Copying Arrays
Calling Functions without Apply
Destructuring Arrays
Function Arguments as Rest Parameters
Using Math Functions
Combining Two Objects
Separate a String into Separate Characters
The [...something] is the spread operator. It in essence allows for an array or string to be expanded. You will see it used often in React, but has many other use cases.
MDN has great documentation on the spread operator:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
You can use "..." in an object. In this example below, "...data" gets 'name: "John", age: 24':
const data= { name: "John", age: 24 };
const newData = {
...data, // Here
sex: "Male"
}
console.log(newData);
This is the result:
{ name: "John", age: 24, sex: "Male" }
This is other example with "...data[key]" to add "id" to each object in an array:
const data = [
{ name: "John", age: 24 },
{ name: "Marry", age: 18 },
{ name: "Tom", age: 15 },
]
const newData = [];
for(const key in data) {
const obj = {
id: Number(key),
...data[key] // Here
}
newData.push(obj);
}
console.log(newData);
This is the result:
[
{ id: 0, name: "John", age: 24 },
{ id: 1, name: 'Marry', age: 18 },
{ id: 2, name: 'Tom', age: 15 }
]
Context: One of the use cases is to do a "copy", but you should take care of this particular "by reference" behavior when working with sub-properties.
Finding: Take care that sub-properties are NOT passed by value, but by reference. In other words, only first level properties are passed as a copy "by value". See the example:
sourcePerson = { name: 'John', colors: ["red", "blue"] }
targetPerson = { ...sourcePerson }
console.log("Target person result:\n", JSON.stringify(targetPerson), "\n\n") //it seems a copy, but...
console.log("Let's update the name source value:\n")
sourcePerson.name = 'Kevin'
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is NOT updated, It keeps a copy by value\n")
console.log(JSON.stringify(targetPerson), "\n\n")
//But if you update a sub-property, it has NOT been copied by value
console.log("Let's update a color sub-property:\n")
sourcePerson.colors[0] = "YELLOW"
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetPerson)) // it is not a copy, it is a reference!
console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level properties, but 'by reference' for sub-properties, so take care!\n")

Loop through an array of objects and get where object.field equals value

I'm currently working on a small application where I have to loop through an enormous array of objects. What would be the most efficient method to perform this?
var array = [
{
id: "1",
name: "Alpha"
},
{
id: "2",
name: "Beta"
},
...
];
I'd like to get each object where name equals "Alpha". I'm currently using a simple if statement to filter the objects with a different name value out, but I wonder if there's a more efficient way to do this, performance-wise.
It's worth to mention that I'll push the matching results into a new array.
No, there is no more efficient way.
The alternative is to build and maintain some kind of internal data structure which allows you to find the desired elements faster. As usual, the trade off is between the work involved in maintaining such a structure vs the time it saves you.
I don't have any way about which I would know it's more effective.
But if you had your objects ordered by name you could stop your search imideatly upon reaching an object whose name is not equal to "Alpha".
To find the first object you're looking for you can use binary search and from this Object you go up and down until at both ends you reach an object which isn't named "Alpha" or the end of array.
This is only a way of optimizing and will require time to sort the array and also will take more time when adding an element.
There's a JavaScript function exactly for this kind of task. Filter
From the Docs
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Here is a small example by code for getting all element from array which has a certain 'name' field:
const arr = [
{name: 'Abc'},
{name: 'Xyz'},
{name: 'Lmn'},
{name: 'Xyz'},
{name: 'Xyz'}
];
let response = findByName('Xyz');
console.log(response);
function findByName (name) {
return arr.filter((element) => {
return element.name = name;
});
}
If you need more than one time a collection with a given name, you could use an object with the names as hashes and have instantly access to the items.
var array = [{ id: "1", name: "Alpha" }, { id: "2", name: "Beta" }, { id: "3", name: "Beta" }, { id: "4", name: "Gamma" }, { id: "5", name: "Beta" }, { id: "2", name: "Alpha" }],
hash = Object.create(null);
array.forEach(function (a) {
if (!hash[a.name]) {
hash[a.name] = [];
}
hash[a.name].push(a);
});
console.log(hash);
.as-console-wrapper { max-height: 100% !important; top: 0; }

JavaScript Syntax Explanation - return { ...state}; [duplicate]

I have a problem with code I am supposed to work with. I found a syntax I am not familiar with and I have trouble googling the documentation:
export const Something = class Something {
constructor(someObject = {}) {
this.someObject = {...Something.someObjectDefaultAsStaticMethod,...someThing};
};
// The rest of the class
};
I have problems understanding what the three dots (...) in front of the parameter do. And "dots in parameter javascript" is a bad search term. Can someone help me, maybe tell me what this syntax is actually called or just directly link me to documentation?
That is not ES6 but has only been added in ECMAScript 2018.
It is called "Object Rest/Spread Properties" and is part of the Spread Syntax.
... (three dots in Javascript) is called the Spread Syntax or Spread Operator. This allows an iterable such as an array expression or string to be expanded or an object expression to be expanded wherever placed.
I want to list down the mostly used practical Use Cases of the Spread Syntax (Spread Operator). The following has been explained with examples in this stackoverflow answer.
Combine Arrays (Concatenate Arrays)
Copying Arrays
Calling Functions without Apply
Destructuring Arrays
Function Arguments as Rest Parameters
Using Math Functions
Combining Two Objects
Separate a String into Separate Characters
The [...something] is the spread operator. It in essence allows for an array or string to be expanded. You will see it used often in React, but has many other use cases.
MDN has great documentation on the spread operator:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
You can use "..." in an object. In this example below, "...data" gets 'name: "John", age: 24':
const data= { name: "John", age: 24 };
const newData = {
...data, // Here
sex: "Male"
}
console.log(newData);
This is the result:
{ name: "John", age: 24, sex: "Male" }
This is other example with "...data[key]" to add "id" to each object in an array:
const data = [
{ name: "John", age: 24 },
{ name: "Marry", age: 18 },
{ name: "Tom", age: 15 },
]
const newData = [];
for(const key in data) {
const obj = {
id: Number(key),
...data[key] // Here
}
newData.push(obj);
}
console.log(newData);
This is the result:
[
{ id: 0, name: "John", age: 24 },
{ id: 1, name: 'Marry', age: 18 },
{ id: 2, name: 'Tom', age: 15 }
]
Context: One of the use cases is to do a "copy", but you should take care of this particular "by reference" behavior when working with sub-properties.
Finding: Take care that sub-properties are NOT passed by value, but by reference. In other words, only first level properties are passed as a copy "by value". See the example:
sourcePerson = { name: 'John', colors: ["red", "blue"] }
targetPerson = { ...sourcePerson }
console.log("Target person result:\n", JSON.stringify(targetPerson), "\n\n") //it seems a copy, but...
console.log("Let's update the name source value:\n")
sourcePerson.name = 'Kevin'
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is NOT updated, It keeps a copy by value\n")
console.log(JSON.stringify(targetPerson), "\n\n")
//But if you update a sub-property, it has NOT been copied by value
console.log("Let's update a color sub-property:\n")
sourcePerson.colors[0] = "YELLOW"
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetPerson)) // it is not a copy, it is a reference!
console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level properties, but 'by reference' for sub-properties, so take care!\n")

Categories