I have to find a property in array of objects by value which is a list of strings.
For example I have someting like this:
const colors ={
colors-1: [{color: 'blue'}],
colors-2: [{color: 'gray'}, {color: 'red'}],
colors-3: [{color: 'white'}]
}
And I want to get for example property colors-2
by string which is inside array value.
Something like this:
findPropertyByValue(colors, 'red')
And output:
'colors-2'
Could You show me how to achieve this? Thank You.
CodePudding user response:
Here is how you could achieve what you want. Notice I added your object keys in quotes, because they contain -
, it wouldn't work other way.
const colors = {
"colors-1": [{ color: "blue" }],
"colors-2": [{ color: "gray" }, { color: "red" }],
"colors-3": [{ color: "white" }]
};
function findPropertyByValue(colors, value) {
for (let color in colors) {
if (colors[color].some((c) => c.color == value)) {
return color;
}
}
return ""; // if there isn't one
}
console.log(findPropertyByValue(colors, "red"));
CodePudding user response:
Here is a solution using find
and some
.
It takes the entries of the colors
object and finds the entry which has an element with the input color.
The find returns an entry with [key,value]
so to get key take the 0th element
Here I assumed that a single color has a unique key.
added the ?.
before [0]
(optional chaining - access only if available) so that when a color that is not found is input there will be no errors (returns undefined
). ||
operator used to return a message like "not found" if the find step returns undefined
const colors ={
'colors-1': [{color: 'blue'}],
'colors-2': [{color: 'gray'}, {color: 'red'}],
'colors-3': [{color: 'white'}]
}
const findPropertyByValue = (obj,col) => Object.entries(obj).find(([k,v])=>v.some(({color}) => color===col))?.[0] || 'not found'
console.log(findPropertyByValue(colors,'white'))
console.log(findPropertyByValue(colors,'gray'))
console.log(findPropertyByValue(colors,'red'))
console.log(findPropertyByValue(colors,'blue'))
console.log(findPropertyByValue(colors,'green'))
CodePudding user response:
The below may be one possible solution to achieve the desired objective:
Code Snippet
const findPropertyByValue = (haystack, needle) => (
Object.keys(haystack)
.find(
k => (haystack[k]).some(
({color}) => color === needle
)
) || 'not found'
);
const colors ={
"colors-1": [{color: 'blue'}],
"colors-2": [{color: 'gray'}, {color: 'red'}],
"colors-3": [{color: 'white'}]
};
console.log('find red: ', findPropertyByValue(colors, 'red'));
console.log('find cyan: ', findPropertyByValue(colors, 'cyan'));
Explanation
- Iterate over the object's (
haystack
) keys .find
in the value array an element whosecolor
prop matchesneedle
(the color being searched)- If any such a match is found, then return the key
- Else, return
not found
CodePudding user response:
You can try this:
const colors = {
"colors-1": [{ color: "blue" }],
"colors-2": [{ color: "gray" }, { color: "red" }],
"colors-3": [{ color: "white" }],
};
function findPropertyByValue(obj, colorName) {
return Object.entries(obj).find((entry) =>
entry[1].some((color) => color.color === colorName)
)?.[0];
}
console.log(findPropertyByValue(colors, "red"));
console.log(findPropertyByValue(colors, "not in list"));
And this solution will return all fields with specified color:
const colors = {
"colors-1": [{ color: "blue" }],
"colors-2": [{ color: "gray" }, { color: "red" }],
"colors-3": [{ color: "white" }],
"colors-4": [{ color: "white" }, { color: "red" }],
};
function findPropertyByValue(obj, colorName) {
return Object.entries(obj).reduce(
(acc, entry) =>
entry[1].some((color) => color.color === colorName)
? [...acc, entry[0]]
: acc,
[]
);
}
console.log(findPropertyByValue(colors, "red"));
console.log(findPropertyByValue(colors, "not in list"));