编辑JSON对象-寻找更好的功能方法
Edit JSON object - looking for better functional approch
我有一个JSON对象设置,类似于这样:
var settings = {
tab1: {
active: true,
selectOrder: 1,
selected: false
},
tab2: {
active: true,
selectOrder: 2,
selected: false
},
tab3: {
active: false,
selectOrder: 0,
selected: false
}
};
现在,我的目标是为具有最低'selectedOrder'的活动元素设置'selected'属性为'true'。在这个例子中,我应该为'tab1'元素设置'selected' ('tab3'的selectedOrder为0,但不是活动的)。
其背后的原因是选择第一个活动选项卡根据其优先级(selectOrder)。
我的解决方案是:
function selectFirstActiveTab(visibilitySettings) {
var selected = 1000;
var answer = jQuery.extend({}, visibilitySettings);
Object.keys(answer).forEach((key) => {
if (answer[key].active && answer[key].selectOrder <= selected) {
selected = answer[key].selectOrder;
}
});
Object.keys(answer).forEach((key) => {
answer[key].selected = (answer[key].selectOrder === selected) ? true : false;
});
return answer;
};
虽然这个解决方案是有效的,但它似乎是一个糟糕的解决方案。
我的问题是:
是否有更好的"函数式编程"方法?(例如使用map/reduce等)
我感觉我的设置对象结构不太好。也许我应该选择对象数组而不是JSON?选择像这样的JSON的原因是为了更简单地绑定到我的模板(像"{{settings .tab1。Selected}}" -比在我的html中查找更简单)。这里应该有什么更好的方法?
- 对于
Object
上的map和reduce,您可以使用下划线:
function selectFirstActiveTab(visibilitySettings) {
// Clone input, with selected set to false.
var answer = _.mapObject(visibilitySettings, (item, key) => {
return {active: item.active, selectOrder: item.selectOrder, selected: false};
});
// Find the min among all value.
var minObj = _.reduce(answer, (min, item) => {
return (item.active && item.selectOrder < min.selectOrder) ? item : min;
}, {active: true, selectOrder: Number.MAX_SAFE_INTEGER});
// Set min to selected.
minObj.selected = true;
return answer;
};
jsBin
或香草javascript:
function selectFirstActiveTab(visibilitySettings) {
var keys = Object.keys(visibilitySettings);
// Create a cloned obj, like map
var answer = {};
keys.forEach((key) => {
var cloneTarget = visibilitySettings[key];
answer[key] = {
active: cloneTarget.active,
selectOrder: cloneTarget.selectOrder,
selected: false
};
});
// Convert key => value map to an array of value, then reduce it to find min.
var minimun = keys.map((key) => answer[key]).reduce((min, item) => {
return (item.active && item.selectOrder < min.selectOrder) ? item : min;
}, {active: true, selectOrder: Number.MAX_SAFE_INTEGER});
// Set min to selected.
minimun.selected = true;
return answer;
};
jsBin
- 它不是
JSON
,它只是一个普通的Object
与一些键值映射,我们使用它作为Map
。如果输入是一个像 这样的数组,那么应用上面的逻辑可能会更容易:
var settings = [
{
name: 'tab1',
active: true,
selectOrder: 1,
selected: false
},
{
name: 'tab2',
active: true,
selectOrder: 2,
selected: false
},
{
name: 'tab3',
active: false,
selectOrder: 0,
selected: false
}
];
作为香草javascript支持减少/映射在array
。然而,像lodash、underscore这样的许多库只是使reduce/map在对象上可用。你可以只需选择最适合您需求的一个(因为有许多类似的库,使您能够通过对象映射/减少)。
使用lodash,您可以编写以下内容:
import { chain, transform, extend } from 'lodash';
transformObj = (obj) => chain(settings)
.map((obj, key)=> ({ key, obj }))
.select(({ obj: { active }})=> active)
.min(({ obj: { selectOrder }})=> selectOrder)
.thru(({ key })=> transform(settings, (memo, val, _key) => {
memo[_key] = extend({}, val, {
selected: (_key == key)
})
}, {})
)
.value()
> transformObj(settings)
{ tab1: { active: true, selectOrder: 1, selected: true },
tab2: { active: true, selectOrder: 2, selected: false },
tab3: { active: false, selectOrder: 0, selected: false } }
以上假设了ES6导入、箭头函数和参数解构的可用性。否则可以使用babel。
这个功能更强大,因为transformObj
是引用透明的&不会改变它的参数。
Try this:
tmp = 0;
_tab = false;
for ( tab in settings ){
if((settings[tab].active)){
if(!tmp){
tmp = settings[tab].selectOrder;
_tab = tab;
}else if(settings[tab].selectOrder < tmp){
_tab = tab;
}
};
}
settings[_tab].selected = true;
相关文章:
- 有没有一种方法可以修改在使用javascript的媒体功能的媒体查询下创建的样式
- 使用多功能框在 chrome 扩展程序中包含内联自动填充功能的任何方法
- 基本阵列构造的功能方法
- AngularJS控制器之间共享代码/方法/功能
- 制作预制响应功能的最佳方法是什么
- 在触摸屏上实现<缩写>型功能的最干净方法
- 自动排序方法以附加功能
- 识别浏览器 HTML5 功能的推荐方法
- 将javascript方法功能分组到javascript“类”中
- 使用无状态功能组件与调用方法有什么区别
- JS扩展方法的功能
- javascript:在页面加载后执行该功能的最佳方法
- 通过SWT浏览器/ SWT浏览器功能从GWT应用程序调用Java方法
- 处理所需和可选功能参数的推荐方法
- 调用自定义API方法的功能
- 有没有更有效的方法来处理重复的功能
- 这是对象方法的内在功能
- 编辑JSON对象-寻找更好的功能方法
- 将对象简化为字符串的功能方法
- 从对象数组上的属性创建数组的功能方法