根据输入数组处理复杂对象

时间:2019-12-23 16:34:58

标签: javascript arrays ecmascript-6 ecmascript-5

我有一个复杂的对象,并且需要根据输入数组修改此复杂对象内部的属性。图示如下。 我需要根据字段值将它们分组,然后将它们添加到对象的“或”数组(如果字段值相同)。如果不相同,则将其直接添加到“ and”对象数组中。 需要从输入数组中读取每个字段,并检查该字段是否存在于“ filterObj”的“过滤器”中,如果存在,则将其添加至“ and”,否则将其添加至“ or”

两者的格式如下所示

//This is the source object where I need to add the below "arr" based on grouping

let filterObj = {
      "feature": "test",
      "filter": {
                 "and": [
                          { "field": "field1","value": "1"}
                        ]
                }
};

//This array needs to be added to above object by grouping based on field
let obj = [
             {"field" : "field1","value": "2"},
             {"field" : "field2","value": "3"},
             {"field" : "field2","value": "4"},
             {"field" : "field3","value" : "5"}
          ]


我希望输出具有以下格式:

var result = {
              "feature": "test",
              "filter": {
                 "and": [
                          {
                           "or" : [
                                    {"field": "field1","value": "1"},
                                    {"field": "field1", "value": "2"}
                                  ]                      
                          },
                          {
                            "or" : [
                                     {"field": "field2","value": "3"},
                                     {"field": "field2","value": "4"},
                                   ]                      
                          },
                          {  "field": "field3", "value": "5"}
                  ]
              } 
}

// The method that I have tried

filterObj.filter.and.or(...obj) ;// Does not work 


2 个答案:

答案 0 :(得分:2)

您可以通过分组来收集所有相同的字段,并将分组中的值分配给sbt-assembly属性。

and
var filterObj = { feature: "test", filter: { and: [{ field: "field1", value: "1" }] } },
    obj = [{ field: "field1", value: "2" }, { field: "field2", value: "3" }, { field: "field2", value: "4" }, { field: "field3", value: "5" }],
    groups = obj.reduce(
        (r, o) => {
            if (r[o.field]) {
                if (!('or' in r[o.field])) r[o.field] = { or: [r[o.field]] };
                r[o.field].or.push(o);
            } else {
                r[o.field] = o;
            }
            return r;
        },
        (filterObj.filter.and || []).reduce((r, o) => {
            r['or' in o ? o.or[0].field : o.field] = o;
            return r;
        }, {}));

filterObj.filter.and = Object.values(groups);

console.log(filterObj);

答案 1 :(得分:1)

//This is the source object where I need to add the below "arr" based on grouping
let filterObj = {
  "feature": "test",
  "filter": {
    "and": [
      { "field": "field1", "value": "1" }
    ]
  }
};

//This array needs to be added to above object by grouping based on field
let obj = [
  { "field": "field1", "value": "2" },
  { "field": "field2", "value": "3" },
  { "field": "field2", "value": "4" },
  { "field": "field3", "value": "5" }
]
//obj = [{ "field": "field1", "value": "2" }]

let all_filters = [];
if (filterObj.filter.and && filterObj.filter.and.hasOwnProperty('or')) {
  all_filters = [...filterObj.filter.and.or];
} else if (filterObj.filter.and) {
  all_filters = [...filterObj.filter.and];
}
const all_objs = [...obj, ...all_filters];
// const all_objs = [...obj, ...filterObj.filter.and];
const uniqKeys = all_objs.reduce((acc, curr) => [...new Set([...acc, curr.field])], []);
const updateItems = uniqKeys.map(obj => {
  const filter_items = all_objs.filter(item => item.field === obj);
  let resultObj = {};
  if (filter_items && filter_items.length > 1) {
    resultObj.or = [...filter_items];
  } else if (filter_items && filter_items.length == 1) {
    resultObj = { ...filter_items[0] };
  }
  return resultObj;
})

var result = {...filterObj, filter: { and: [...updateItems] }};

console.log(result);

请不要在您的输入中包含“ fiedl2”和“ field2”(两个不同)。我在这里的数据中更新为相同的字段名称