我要对以下对象进行排序
class A{
public:
int x;
int getA(){return x;}
int getB(){return this->x;}
void setA(int val){ x = val;}
void setB(int val){ this->x = val;}
};
int main(int argc, const char * argv[]) {
A objectA;
A objectB;
object.setA(33);
std::cout<< object.getA() << "\n";
objectB.setB(32);
std::cout<< object.getB() << "\n";
return 0;
}
我正在实现带有嵌套复选框的表单,其值可以是“ Y”或“ N”。我只想捕获“ Y”复选框,并且如果所有子复选框都为“ Y”,则我想丢弃它们并仅获得父复选框。上面是具有所有复选框值的对象。我希望将对象排序为:
const form = {
A_ALL: {A1_ALL: { A1_ONE: 'Y', A2_TWO: 'Y', A3_THREE: 'Y'}, A2: {A2_FOUR: 'Y', A2_FIVE: 'N', A2_SIX: 'Y'}, A3: 'Y', A4: 'N'},
B_ALL: {B1_ALL: { B1_ONE: 'Y', B1_TWO: 'Y', B1_THREE: 'Y'}, B2: {B2_FOUR: 'Y', B2_FIVE: 'Y', B2_SIX: 'Y'}, B3: 'Y', B4: 'Y'},
C_ALL: {XX: 'Y', YY:'Y'},
D: 'Y',
E: 'N'
}
到目前为止,我的代码如下:
{
A_ALL: {A1_ALL: 'Y', A2: {A2_FOUR: 'Y', A2_SIX: 'Y'}, A3: 'Y'},
B_ALL : 'Y',
C: 'Y',
D: 'Y'
}
答案 0 :(得分:1)
您已尝试关闭,只需要递归调用map
即可在对象值中找到的每个对象。
const form = { A_ALL: {A1_ALL: { A1_ONE: 'Y', A2_TWO: 'Y', A3_THREE: 'Y'}, A2: {A2_FOUR: 'Y', A2_FIVE: 'N', A2_SIX: 'Y'}, A3: 'Y', A4: 'N'}, B_ALL: {B1_ALL: { B1_ONE: 'Y', B1_TWO: 'Y', B1_THREE: 'Y'}, B2: {B2_FOUR: 'Y', B2_FIVE: 'Y', B2_SIX: 'Y'}, B3: 'Y', B4: 'Y'}, C_ALL: {XX: 'Y', YY:'Y'}, D: 'Y', E: 'N' }
const eY = R.equals('Y')
const isSelected = R.compose(R.all(eY), R.values)
const groupValue = R.when(isSelected, R.always('Y'))
const fn = objOrString => R.pipe(
R.unless(R.is(String), R.map(fn)),
R.unless(R.is(String), groupValue),
R.unless(R.is(String), R.filter(R.either(R.is(Object), R.equals('Y'))))
)(objOrString)
console.log(fn(form))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
答案 1 :(得分:0)
我有一个局部解决方案,目前没有时间进行下一步。本质上,它过滤掉不是'Y'
的所有值。然后,您应该能够通过递归地替换仅包含'Y'
个值的对象(仅包含'Y'
个值的对象)来增加精简的步骤。
const form = {
A_ALL: {A1_ALL: { A1_ONE: 'Y', A2_TWO: 'Y', A3_THREE: 'Y'}, A2: {A2_FOUR: 'Y', A2_FIVE: 'N', A2_SIX: 'Y'}, A3: 'Y', A4: 'N'},
B_ALL: {B1_ALL: { B1_ONE: 'Y', B1_TWO: 'Y', B1_THREE: 'Y'}, B2: {B2_FOUR: 'Y', B2_FIVE: 'Y', B2_SIX: 'Y'}, B3: 'Y', B4: 'Y'},
C_ALL: {XX: 'Y', YY:'Y'},
D: 'Y',
E: 'N'
}
const isObject = s => Object.prototype.toString.call(s) == '[object Object]'
const isArray = s => Object.prototype.toString.call(s) == '[object Array]'
const collect = pairs => pairs.reduce(
(a, [k, v]) => ({...a, [k]: isArray(v) ? collect(v) : v}),
{}
)
const spread = val => obj => Object.entries(obj)
.filter(([k, v]) => v == val || isObject(v))
.map(([k, v]) => isObject(v) ? [k, spread(val)(v)] : [k, v])
const findMatchingKeys = (val, obj) => collect(spread(val)(obj))
console.log(findMatchingKeys('Y', form))
此解决方案不使用Ramda。我是Ramda的创始人之一,也是图书馆的忠实拥护者,但我没有看到Ramda在这里提供很多帮助,只是进行了一些小的清理工作。
答案 2 :(得分:0)
这里的方法略有不同,(确实)产生的结果与Scott Christopher的答案相同:
// Ramda doesn't support folding objects, so we have to define this here
// :: Monoid m -> (a -> m) -> StrMap a -> m
const foldMap = M => f => o =>
R.keys(o).reduce((p, c) => M.append(p)(f(o[c])), M.empty);
// :: Monoid Boolean
const And = { empty: true, append: x => y => x && y };
// Each layer of the form can be thought of as a string map, where
// a key is mapped to one of the strings "Y" or "N", or to a value
// of some given type `a`
// :: type ValueOr a = "Y" | "N" | a
// :: type FormLayer a = StrMap (ValueOr a)
// We can think of a form as an infinite nesting of form layers
// :: type Fix f = f (Fix f)
// :: type Form = Fix FormLayer
// = FormLayer (FormLayer (FormLayer (FormLayer ...)))
// Recursion schemes can help us promote a function for operating
// on one layer of the structure to a function that operates on an
// infinite nesting of layers
// :: Functor f -> (f a -> a) -> Fix f -> a
const cata = F => alg => {
const rec = x => alg(F.map(rec)(x));
return rec;
};
// It's useful to factor repeated case analysis into a pattern
const ValOr = {
Y: "Y",
N: "N",
Other: x => x,
match: ({ Y, N, Other }) => v => v === "Y" ? Y : v === "N" ? N : Other(v),
map: f => ValOr.match({ Y, N, Other: f })
};
const { Y, N, Other } = ValOr;
// :: Functor FormLayer
const FormLayer = { map: f => R.map(ValOr.map(f)) };
// :: ValueOr _ -> Boolean
const isY = ValOr.match({ Y: true, N: false, Other: _ => false });
// :: FormLayer _ -> Boolean
const allYs = foldMap(And)(isY);
// :: Form -> ValueOr Form
const squashYs = cata(FormLayer)(o => allYs(o) ? Y : Other(o));
// :: ValueOr _ -> Boolean
const isntN = ValOr.match({ Y: true, N: false, Other: _ => true });
// :: Form -> Form
const filterNs = cata(FormLayer)(R.filter(isntN));
// :: Form -> ValueOr Form
const f = R.pipe(
// Squash Y-only objects recursively
squashYs,
// If the top level result is still a form, filter out the "N"s recursively
ValOr.match({ Y, N, Other: filterNs })
);
// :: Form
const form = {
A_ALL: {
A1_ALL: { A1_ONE: "Y", A2_TWO: "Y", A3_THREE: "Y" },
A2: { A2_FOUR: "Y", A2_FIVE: "N", A2_SIX: "Y" },
A3: "Y",
A4: "N"
},
B_ALL: {
B1_ALL: { B1_ONE: "Y", B1_TWO: "Y", B1_THREE: "Y" },
B2: { B2_FOUR: "Y", B2_FIVE: "Y", B2_SIX: "Y" },
B3: "Y",
B4: "Y"
},
C_ALL: { XX: "Y", YY: "Y" },
D: "Y",
E: "N"
};
// :: ValueOr Form
const result = f(form);
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>