【问题标题】:How to filter records based on the status value in JavaScript object?如何根据 JavaScript 对象中的状态值过滤记录?
【发布时间】:2018-08-01 02:37:34
【问题描述】:

我有一个看起来像这样的 JS 对象:

{
  "3": {
    "id": 3,
    "first": "Lisa",
    "last": "Morgan",
    "email": "lmorgan@gmail.com",
    "phone": "(508) 233-8908",
    "status": 0
  },
  "4": {
    "id": 4,
    "first": "Dave",
    "last": "Hart",
    "email": "dhart@gmail.com",
    "phone": "(509) 874-9411",
    "status": 1
  }
}

我想过滤对象,例如只提取状态为“1”的记录。一种解决方案是使用这样的数组过滤器:

var filterJSON = Object.values(obj).filter(function (entry) {
                switch(frmFilter){
                    case '1':
                        return entry.status === 1;
                        break;
                    case '2':
                        return entry.status === 0;
                        break;
                    default:
                        return entry;
                }
            });

问题是上面的代码会将数据转换成这样的数组:

[
  {
    "id": 3,
    "first": "Lisa",
    "last": "Morgan",
    "email": "lmorgan@gmail.com",
    "phone": "(508) 233-8908",
    "status": 1
  },
  {
    "id": 4,
    "first": "Dave",
    "last": "Hart",
    "email": "dhart@gmail.com",
    "phone": "(509) 874-9411",
    "status": 1
  }
]

如您所见,数据集是一个数组,我想在应用过滤器之前将对象中的数据保持与第一个示例中的数据相同。有没有办法通过对象过滤并获得与通过数组过滤相同的输出?

【问题讨论】:

  • for...in 循环帮助吗?
  • @samuellawrentz 也许,我不确定你的建议是什么。

标签: javascript arrays json filter jsobject


【解决方案1】:

您可以使用.filter().reduce() 将过滤后的数组转换回对象:

var obj = {
  "3": {
    "id": 3,
    "first": "Lisa",
    "last": "Morgan",
    "email": "lmorgan@gmail.com",
    "phone": "(508) 233-8908",
    "status": 0
  },
  "4": {
    "id": 4,
    "first": "Dave",
    "last": "Hart",
    "email": "dhart@gmail.com",
    "phone": "(509) 874-9411",
    "status": 1
  }
}

var frmFilter = "1";

var filterJSON = Object.keys(obj).filter(function (key) {
    let entry = obj[key];
    switch(frmFilter){
        case '1':
            return entry.status === 1;
            break;
        case '2':
            return entry.status === 0;
            break;
        default:
            return entry;
    }
}).reduce( (res, key) => (res[key] = obj[key], res), {} );

console.log(filterJSON);

从这个答案中得到了一些帮助:JavaScript: filter() for Objects

【讨论】:

  • 你能解释一下你的答案吗?我不熟悉reduce() 方法。
  • @espresso_coffee 查看我发布的链接。 javascript 文档比我能给出的任何解释都要好,并且会提供许多示例。
【解决方案2】:

试试这个:

const data = {
  "3": {
    "id": 3,
    "first": "Lisa",
    "last": "Morgan",
    "email": "lmorgan@gmail.com",
    "phone": "(508) 233-8908",
    "status": 0
  },
  "4": {
    "id": 4,
    "first": "Dave",
    "last": "Hart",
    "email": "dhart@gmail.com",
    "phone": "(509) 874-9411",
    "status": 1
  }
};

const filtered = Object.values(data).filter(e => e.status == 1);
const output = {};
filtered.forEach(e => output[e.id] = e);
console.log(output);

【讨论】:

  • 我可以像在我的示例中那样在过滤器中使用switch吗?
  • @espresso_coffee 可以,但是过滤器需要返回一个bool,查看修改后的代码它将过滤结果并重建一个对象。
  • 这不是假设嵌套对象中的'id'字段与父对象中的键相同吗?
  • @AbidHasan 是的
  • 如果您要将项目映射到输出,而不是从映射返回任何内容,您只需在 filtered 上使用 .forEach()
【解决方案3】:

如果你使用过滤器数组函数,它返回一个简单的数组,而不是像原来的对象(obj

你可以做一个简单的for-each复制和修改另一个对象中的对象属性:

var filterJSON = {};
for (var key in obj) {
  if (obj.hasOwnProperty(key)){

        switch(frmFilter){
                case '1':
                    if (filterJSON[key].status == 1){
                       filterJSON[key] = obj[key];
                    } 
                    break;
                case '2':
                    if (filterJSON[key].status == 0){
                       filterJSON[key] = obj[key];
                    }
                    break;
         }
   }
}

【讨论】:

  • 每当你循环一个对象时,总是检查对象是否hasOwnProperty。此外,此代码根本不起作用。 filterJSON[key].status === 1 什么都不做。
【解决方案4】:

这就是你要找的东西:

const filter = (data, predicate) => {
  return Object.keys(data).reduce((acc, current) => {
    if (predicate(data[current])) {
      acc[current] = data[current];
    }
    return acc;
  }, {});
}

// result contains only items with status of 1
const result = filter(data, (item) => item.status === 1);

// result2 contains only items with last name of length > 4
const result2 = filter(data, (item) => item.last.length > 4);

对每个项目调用谓词,如果它返回 true,则该项目将包含在结果中。

【讨论】:

    【解决方案5】:

    我在告诉 JS 中的 for...in 循环,它用于迭代对象的属性。

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

    var obj = {
      "3": {
        "id": 3,
        "first": "Lisa",
        "last": "Morgan",
        "email": "lmorgan@gmail.com",
        "phone": "(508) 233-8908",
        "status": 0
      },
      "4": {
        "id": 4,
        "first": "Dave",
        "last": "Hart",
        "email": "dhart@gmail.com",
        "phone": "(509) 874-9411",
        "status": 1
      }
    }
    var filteredObj = {};
    for (var props in obj){
      if(obj[props].status===1)
      filteredObj[props] = obj[props] ; 
      }
      
      console.log(filteredObj)

    您正在迭代 obj 的属性并检查状态。如果 status 等于 1,我们将该属性分配给 filteredObj 对象。

    【讨论】:

      猜你喜欢
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 2020-12-03
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多