减少筛选JS对象的函数

huangapple go评论66阅读模式
英文:

Reducing the function that filters the JS object

问题

Sure, here's the translated code portion you requested:

我有一个类似这样的JS对象

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":""}]"}

我想创建一个函数它返回这样一个对象不包含字符串数组字段例如**"settings":"[{"ip":""}]"**并且如果这个数组只包含一个元素并且这个对象只包含一个键值对值为空字符串

期望的结果是

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26"}

不应该过滤的数组

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":"33333not empty"}]"}
或者

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":"345", "dns": "address"}]"}

我编写了以下函数

Please note that I've translated the code portion as requested, but I haven't provided any answers to your questions or comments in the code. If you need further assistance or have questions about the code, please let me know.

英文:

I have a JS object like this:

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":""}]"}

I would like to create a function which returns such object without field which is string-array "settings":"[{"ip":""}]" and if this array contains only one element and if this object contains only one key-value pair with value of empty string.

Desired result is:

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26"}

Arrays not to be filtered:

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":"33333not empty"}]"}

or:

{"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":"345", "dns": "address"}]"}

I wrote the following function:

    function filterArrayFields(values) {
const result = {};
const fieldNames = Object.keys(values);
fieldNames.forEach((fieldName) => {
if (typeof values[fieldName] !== 'string') {
result[fieldName] = values[fieldName];
return;
}
try {
const parsedValue = JSON.parse(values[fieldName]);
if (!Array.isArray(parsedValue)) {
result[fieldName] = values[fieldName];
return;
}
if (Array.isArray(parsedValue) && parsedValue.length > 1) {
result[fieldName] = values[fieldName];
return;
}
if (Array.isArray(parsedValue) && parsedValue.length === 1) {
const arrayTypeFieldValue = parsedValue[0];
const [arrayTypeFieldValueName] = Object.keys(arrayTypeFieldValue);
if (arrayTypeFieldValue[arrayTypeFieldValueName] !== '') {
result[fieldName] = values[fieldName];
return;
}
}
} catch (error) {
result[fieldName] = values[fieldName];
}
});
return result;
}

This method is working correctly but it looks like that it is overloaded buy if-s or extra conditions. Is it possible to optimize this function anyhow?

Edit: our target field can have any name, not only 'settings' - 'settings' here is just an example

答案1

得分: 2

我认为你可以通过使用扩展运算符 浅克隆输入对象,并在只有满足条件时有条件地合并设置来显著简化这个部分。

条件测试可以由一个单独的专用函数处理。类似于这样:

function stripEmptySettings(obj) {
  const { settings, ...rest } = obj;
  return {
    ...rest,
    ...stripSettings(JSON.parse(settings)),
  };
}

function stripSettings(settings) {
  if (
    settings?.length === 1
    && Object.keys(settings[0]).length === 1
    && Object.values(settings[0]).every(v => v === '')
  ) {
    return;
  }
  return { settings };
}

const inputs = [
  {"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":" "}]"},
  {"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":"33333not empty"}]"},
  {"field1":1,"field3":14,"category":9,"completion":null,"creation":"23-04-26", "settings":"[{"ip":"345", "dns": "address"}]"}
];

const results = inputs.map(stripEmptySettings);

console.log(JSON.stringify(results, null, 3));

希望这可以帮助你。

英文:

I think you could tighten this up significantly by shallow-cloning the input object via the spread operator and conditionally merging the settings back in only if it meets your criteria.

The criteria testing could be handled by a separate dedicated function. Something like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function stripEmptySettings (obj) {
const { settings, ...rest } = obj;
return {
...rest,
...stripSettings(JSON.parse(settings)),
}
}
function stripSettings (settings) {
if (
settings?.length === 1
&amp;&amp; Object.keys(settings[0]).length === 1
&amp;&amp; Object.values(settings[0]).every(v =&gt; v === &#39;&#39;)
) {
return;
}
return {settings};
}
const inputs = [
{&quot;field1&quot;:1,&quot;field3&quot;:14,&quot;category&quot;:9,&quot;completion&quot;:null,&quot;creation&quot;:&quot;23-04-26&quot;, &quot;settings&quot;:&quot;[{\&quot;ip\&quot;:\&quot;\&quot;}]&quot;},
{&quot;field1&quot;:1,&quot;field3&quot;:14,&quot;category&quot;:9,&quot;completion&quot;:null,&quot;creation&quot;:&quot;23-04-26&quot;, &quot;settings&quot;:&quot;[{\&quot;ip\&quot;:\&quot;33333not empty\&quot;}]&quot;},
{&quot;field1&quot;:1,&quot;field3&quot;:14,&quot;category&quot;:9,&quot;completion&quot;:null,&quot;creation&quot;:&quot;23-04-26&quot;, &quot;settings&quot;:&quot;[{\&quot;ip\&quot;:\&quot;345\&quot;, \&quot;dns\&quot;: \&quot;address\&quot;}]&quot;}
]
const results = inputs.map(stripEmptySettings);
console.log(JSON.stringify(results, null, 3));

<!-- end snippet -->

答案2

得分: 1

JS有一个内置的筛选函数。对于使用JSON.stringify()JSON.parse()的设置值,这将是序列化数组的最简单方式。

const filteredList = fieldNames.filter(field => {
  if ("settings" in field) {
    let settings = JSON.parse(field.settings);
    if (
      settings.length > 0 &&
      settings[0]
    ) {
      let nonEmpty = false;
      const keys = Object.keys(settings[0]);
      for (let i = 0; i < keys.length; i++) {
        if (settings[0][keys[i]]) {
          nonEmpty = true;
          break;
        }
      }
      return nonEmpty;
    }
    return false;
  }
  return true;
});
英文:

JS has a builtin filter function. For the settings value using JSON.stringify() and JSON.parse() will be the easiest way to serialize the array

const filteredList = fieldNames.filter(field =&gt; {
if(&quot;settings&quot; in field){
let settings = JSON.parse(field.settings)
if(
settings.length &gt; 0 &amp;&amp;
settings[0]
){
let nonEmpty = false
const keys = Object.keys(settings[0])
for(let i =0; i &lt; keys.length; i ++){
if(settings[0][keys[i]]){
nonEmpty = true
break
}
}
return nonEmpty
}
return false
}
return true
})

huangapple
  • 本文由 发表于 2023年4月20日 00:18:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76056774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定