【问题标题】:es6 filter JSON returns undefined, filter object does notes6过滤器JSON返回未定义,过滤器对象没有
【发布时间】:2017-07-02 11:13:01
【问题描述】:

我有一个过滤器函数,它仅在将 JSON 传递给它时才返回 undefined。我想用这个函数来过滤对象、JSON 或任何东西。在对象和 JSON 上进行这项工作的最佳方法是什么?

let a = [{
  "employees": {
    "employee": [{
      "id": "1",
      "firstName": "Tom",
      "lastName": "Cruise"
    }, {
      "id": "2",
      "firstName": "Maria",
      "lastName": "Sharapova"
    }, {
      "id": "3",
      "firstName": "James",
      "lastName": "Bond"
    }]
  }
}];

var b = [{
  name: '',
  grade: 'x'
}, {
  name: 'yaya',
  grade: 'x'
}, {
  name: 'x',
  frade: 'd'
}, {
  name: 'a',
  grade: 'b'
}];

function findIt(arr, searchKey) {
  return arr.filter(obj => Object.keys(obj).some(key => obj[key].includes(searchKey)));
}

if (a) {
  console.log("I found: ", findIt(a, "James")); // breaks
}

if (b) {
  console.log("I found: ", findIt(b, "yaya")); // works fine
}

【问题讨论】:

标签: javascript json ecmascript-6


【解决方案1】:

您需要对内部数组的引用进行搜索。

findIt(a[0].employees.employee, "James"));
//      ^^^^^^^^^^^^^^^^^^^^^^

let a = [{ employees: { employee: [{ id: "1", firstName: "Tom", lastName: "Cruise" }, { id: "2", firstName: "Maria", lastName: "Sharapova" }, { id: "3", firstName: "James", lastName: "Bond" }] } }];
var b = [{ name: '', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];

function findIt(arr, searchKey) {
    return arr.filter(obj => Object.keys(obj).some(key => obj[key].includes(searchKey)));
}

console.log(findIt(a[0].employees.employee, "James"));
console.log(findIt(b, "yaya"));

要进行更深入的查找,您可以使用递归方法。

function findIt(object, search) {
    function find(k) {
        if (object[k] === search) {
            return result = object;
        }
        return result = findIt(object[k], search);
    }

    var result;
    if (object && typeof object === 'object') {
        Object.keys(object).some(find);
    }
    return result;
}


var a = [{ employees: { employee: [{ id: "1", firstName: "Tom", lastName: "Cruise" }, { id: "2", firstName: "Maria", lastName: "Sharapova" }, { id: "3", firstName: "James", lastName: "Bond" }] } }],
    b = [{ name: '', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];

console.log(findIt(a, "James"));
console.log(findIt(b, "yaya"));
console.log(findIt(a, "foo"));   // undefined
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 嗨@nina Scholz 是否必须像这样访问它:a[0].employees.employee ?
  • 我不能只搜索整棵树吗?
  • 您将不得不递归地检查内部树。您可以将其用作 sample
  • 之所以这么说是因为它是一个 redux 存储,我并不完全确定对象 / json 的结构。
  • @Jimi 一个简单的问题,如果你需要搜索整棵树,为什么要使用.filter。这将为您返回比预期更多的数据
【解决方案2】:

您可以尝试进行字符串搜索。

逻辑

  • 使用JSON.stringify创建对象的副本,但作为字符串
  • 创建一个搜索模式:<something>SearchValue 的正则表达式。
  • 用这个正则表达式测试对象字符串并在过滤器中返回

let a = [{ employees: { employee: [{ id: "1", firstName: "Tom", lastName: "Cruise" }, { id: "2", firstName: "Maria", lastName: "Sharapova" }, { id: "3", firstName: "James", lastName: "Bond" }] } }];
var b = [{ name: '', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];


function findIt(arr, searchKey) {
  let reg = new RegExp(':(.*?)' + searchKey, 'g');
  return arr.filter(obj => reg.test(JSON.stringify(obj)));
}

console.log("I found: ", findIt(a, "James")); // breaks

console.log("I found: ", findIt(a[0].employees.employee, "James")); // breaks

console.log("I found: ", findIt(b, "yaya")); // works fine

【讨论】:

    猜你喜欢
    • 2018-07-31
    • 2016-06-29
    • 2018-03-15
    • 2020-02-12
    • 2017-06-29
    • 2017-12-06
    • 1970-01-01
    • 2012-01-10
    • 2016-07-10
    相关资源
    最近更新 更多