js 判断对象中的值是否相等或为空

数据格式↓

const data = [
    {
        type: 0, 
        params: [
            {
                expression: "0", 
                value: "100"
            }
        ], 
        interest: "9.9"
    }, 
    {
        type: 1, 
        params: [
            {
                expression: "1", 
                value: "285"
            }, 
            {
                expression: "0", 
                value: ""
            }
        ], 
        interest: "9.9"
    }, 
    {
        type: 0, 
        params: [
            {
                expression: "1", 
                value: "100"
            }
        ], 
        interest: "9.9"
    }
]

①判断所有的value值是否有相等,有的话返回false
②判断所有的value值是否有空值,有的话返回false
③判断所有的interest值是否有空值,有的话返回false

在这里先感谢各位大哥大姐的解答,小弟感激不尽!!!

阅读 4.9k
5 个回答

给你一个简单粗暴的写法,😄,有点上头

function valid(json) {
  try { 
    // 先转为字符串,try catch 保证JSON转换程序的健壮性
    const str = JSON.stringify(json)
    // 通过正则匹配空值,null 或 '' 字符串
    if (/"interest":(""|null)/g.test(str) || /"value":(""|null)/g.test(str)) return false
    // 然后正则捕获所有value的键值对,
    const matches = str.match(/"value":[^,}]*/g)
    if (matches) {
      // 通过Set去重
      const set = new Set(matches)
      // 如果和匹配长度不一样,说明有重复项
      if (set.size !== matches.length) return false
    }
    return true
  } catch (e) {
    throw e
  }
}

console.log(valid(data))

可以使用 JSON.stringify 将整个对象转换成字符串再进行比较,至于你说的空值,具体指的是什么内容,null

用源生js的写法,方法有很多,只是其中一种,也方便理解。

下图是我自己改过数据后返回的数据:
image.png

下边是对应的js代码:

let valueArr = [];
// 第一层循环遍历data中的每个对象
for (let i = 0; i < data.length; i++) {
    // 第二层循环遍历data中每个对象的每个params
    for (let n = 0; n < data[i].params.length; n++) {
        let val = data[i].params[n].value;
        // 判断每个params中value的值为空或是为null
        if (val == '' || val == null) {
            console.log(false, '第' + (i + 1) + '个params中的' + (n + 1) + '个value有空值');
        }
        // 与此同时将value的值推送进一个新的空数组中
        valueArr.push(val);
    }
    let inter = data[i].interest;
    // 第一层循环中同时判断每个对象的interest属性的值是否为空或者null
    if (inter == '' || inter == null) {
        console.log(false, '第' + (i + 1) + '个interest为空或null');
    }
}
// 给新数组排序
valueArr.sort();
// 遍历新数组判断前一个值与后一个值是否相等(未判断类型,需要判断类型变为“===”)
for (let i = 0; i < valueArr.length; i++) {
    if (valueArr[i + 1] && valueArr[i] == valueArr[i + 1]) {
        console.log(false, '值为' + valueArr[i] + '的value有相等的值');
    }
}
const data = [
    {
        type: 0, 
        params: [
            {
                expression: "0", 
                value: "100"
            }
        ], 
        interest: "9.9"
    }, 
    {
        type: 1, 
        params: [
            {
                expression: "1", 
                value: "285"
            }, 
            {
                expression: "0", 
                value: ""
            }
        ], 
        interest: "9.9"
    }, 
    {
        type: 0, 
        params: [
            {
                expression: "1", 
                value: "100"
            }
        ], 
        interest: "9.9"
    }
]

//①判断所有的value值是否有相等,有的话返回false
let valueIsEqual = new Set(data.flatMap(({params})=>params.map(({value})=>value))).size!=1;
//②判断所有的value值是否有空值,有的话返回false
let valueIsEmpty = data.every(({params})=>params.every(({value})=>value));
//③判断所有的interest值是否有空值,有的话返回false
let interestIsEmpty = data.every(({interest})=>interest);

if([valueIsEqual, valueIsEmpty, interestIsEmpty].every(item=>item)){
// 都为true
} else {
// 其中有false
}

注意,我给的 data 用例和题主的不同,这个用例会返回 true,题主的用例会返回 false。具体处理过程看注释。

function predicate(data) {
    // 工具函数:isValid 会把 null 和 undefined 转换成 "" 再和 "" 比较,用来判空
    // 也就是说,null, undefined 和 "" 都会识别为 false
    const isValid = v => (v ?? "") !== "";

    // 工具函数:isUnique 会判断 cache 中是否存在某个值,
    // 如果存在,说明发生重复,返回 false
    // 如果不存在,就把这个值加到 cache 中,表示它出现过,用于下一次判断
    // 注意,因为 Set 会区分类型, 100 和 "100" 是两个不同的值
    const cache = new Set();
    const isUnique = v => cache.has(v) ? false : cache.add(v)

    return data.every(
        // 第一层,判断 date 的每个元素,是否同时符合两个条件:
        // 1. interest 非空
        it => isValid(it.interest)
            // 2. 所有参数的 value 是否符合要求
            && (it.params
                // 第二层判断是否所有参数的 value 符合条件,其中
                // ?. 表示如果没有 params 会直接返回 undefined,
                // 所以后面缀了 ?? true 表示如果是 undefined 就改为 true,
                // 也就是处理:没有 params 的情况下,不对 params 进行判断
                ?.every(
                    // 两个条件都必须符合:value 非空,且唯一
                    p => isValid(p.value) && isUnique(p.value)
                ) ?? true))
}

const data = [
    { type: 0, interest: "9.9" },
    {
        type: 0,
        params: [
            { expression: "0", value: "100" }
        ],
        interest: "9.9"
    },
    {
        type: 1,
        params: [
            { expression: "1", value: "285" },
            { expression: "0", value: 285 }
        ],
        interest: "9.9"
    },
    {
        type: 0,
        params: [
            { expression: "1", value: 100 }
        ],
        interest: "9.9"
    }
];

console.log(predicate(data));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题