是数组中的值还是对象 Ramda 中的字符串
Is value in array or string inside object Ramda
这里有点奇怪,我正在解析查询字符串,有时它们作为字符串返回,有时作为字符串数组返回(取决于是否存在一个与多个)。
我想查询key下是否存在value,需要在数据为空或null的情况下工作
# we have access to both the key and value
const key = 'locations'
const value = 'London'
数据的形状如下:
# does 'London' exist under `locations`?
{
locations: 'London',
skills: ['1', '2'],
}
数据的形状也可能如下所示:
{
locations: ['London', 'Reading'],
skills: '1',
}
我考虑过使用 pathSatisfies
、pathEq
和 contains
,但没有成功。我似乎对值可以包含在字符串或数组中这一事实感到困惑。
如评论中所述,使用Array.isArray()
查看属性是否包含数组,如果包含则使用数组方法,否则直接比较值
const key = 'locations',
value = 'London',
data = {
locations: 'London',
skills: ['1', '2'],
},
data2 = {
locations: ['London', 'Reading'],
skills: '1',
}
const hasValue = (data, key, value) => {
const testVal = data[key];
return Array.isArray(testVal) ? testVal.includes(value) : testVal === value;
}
// string version
console.log(hasValue(data, key, value));
// array version
console.log(hasValue(data2, key, value))
如果密钥还没有,我会使用透镜将其转换为阵列。然后你可以简单地使用 propSatisfies
和 includes
:
const toArr = unless(is(Array), of);
const check = (key, value) =>
pipe(
over(lensProp(key), toArr),
propSatisfies(includes(value), key));
console.log(
check('locations', 'London')({locations: ['London', 'Reading']})
);
console.log(
check('locations', 'London')({locations: 'London'})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {unless, is, of, pipe, over, lensProp, propSatisfies, includes} = R;</script>
编辑: 实际上这可以简化为 includes
同时处理字符串和数组:
const check = (key, value) => where({[key]: includes(value)})
console.log(
check('locations', 'London')({locations: 'London'})
);
console.log(
check('locations', 'London')({locations: ['London', 'Reading']})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {where, includes} = R;</script>
这个小函数应该可以帮助您。
function hasValue(obj, key, value) {
if (!obj) return false;
let prop = obj[key];
if (!prop) return false;
if (Array.isArray(prop))
return prop.indexOf(value) >= 0;
return prop === value;
}
这里有点奇怪,我正在解析查询字符串,有时它们作为字符串返回,有时作为字符串数组返回(取决于是否存在一个与多个)。
我想查询key下是否存在value,需要在数据为空或null的情况下工作
# we have access to both the key and value
const key = 'locations'
const value = 'London'
数据的形状如下:
# does 'London' exist under `locations`?
{
locations: 'London',
skills: ['1', '2'],
}
数据的形状也可能如下所示:
{
locations: ['London', 'Reading'],
skills: '1',
}
我考虑过使用 pathSatisfies
、pathEq
和 contains
,但没有成功。我似乎对值可以包含在字符串或数组中这一事实感到困惑。
如评论中所述,使用Array.isArray()
查看属性是否包含数组,如果包含则使用数组方法,否则直接比较值
const key = 'locations',
value = 'London',
data = {
locations: 'London',
skills: ['1', '2'],
},
data2 = {
locations: ['London', 'Reading'],
skills: '1',
}
const hasValue = (data, key, value) => {
const testVal = data[key];
return Array.isArray(testVal) ? testVal.includes(value) : testVal === value;
}
// string version
console.log(hasValue(data, key, value));
// array version
console.log(hasValue(data2, key, value))
如果密钥还没有,我会使用透镜将其转换为阵列。然后你可以简单地使用 propSatisfies
和 includes
:
const toArr = unless(is(Array), of);
const check = (key, value) =>
pipe(
over(lensProp(key), toArr),
propSatisfies(includes(value), key));
console.log(
check('locations', 'London')({locations: ['London', 'Reading']})
);
console.log(
check('locations', 'London')({locations: 'London'})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {unless, is, of, pipe, over, lensProp, propSatisfies, includes} = R;</script>
编辑: 实际上这可以简化为 includes
同时处理字符串和数组:
const check = (key, value) => where({[key]: includes(value)})
console.log(
check('locations', 'London')({locations: 'London'})
);
console.log(
check('locations', 'London')({locations: ['London', 'Reading']})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {where, includes} = R;</script>
这个小函数应该可以帮助您。
function hasValue(obj, key, value) {
if (!obj) return false;
let prop = obj[key];
if (!prop) return false;
if (Array.isArray(prop))
return prop.indexOf(value) >= 0;
return prop === value;
}