使用字符串而不是对象对 return 数组进行续集

Sequelize return array with Strings instead of Objects

有时我只想select多行中的一个值。

假设我有一个如下所示的帐户模型:

帐号

我只想select名字。

你会这样写:

AccountModel.findAll({
        where: {
            Age: {
                $gt : 18
            }
        },
        attributes: ['Name'],
        raw : true
    });

但这会 return 在一个包含对象的数组中。

[{Name : "Sample 1"}, {"Name" : "Sample 2"}]

我想得到一个只有这样名字的数组:

["Sample 1", "Sample 2"]

是否可以使用 Sequelize 实现此目的? 我已经通过文档进行了搜索,但找不到它。

使用 Sequelize 3.13.0 看起来不可能 find return 平面值数组而不是对象数组。

您的问题的一个解决方案是使用下划线或 lodash 映射结果:

AccountModel.findAll({
    where: {
        Age: {
            $gt : 18
        }
    },
    attributes: ['Name'],
    raw : true
})
.then(function(accounts) {
  return _.map(accounts, function(account) { return account.Name; })
})

我已经上传了一个演示此 here 的脚本。

作为快速说明,设置 raw: true 使 Sequelize 查找方法 return 普通旧 JavaScript 对象(即没有实例方法或元数据)。这可能对性能很重要,但在转换为 JSON 后不会更改 returned 值。这是因为 Instance::toJSON 总是 return 是一个普通的 JavaScript 对象(没有实例方法或元数据)。

arr-pluck 效果不错:

var pluck = require('arr-pluck');

AccountModel.findAll({
    where: {
        Age: {
            $gt : 18
        }
    },
    attributes: ['Name'],
    raw : true
})
.then(function(accounts) {
  return pluck(accounts, 'Name');
})

这是一个很好的 ES6 版本的 cfogelberg 使用 lambda 表达式的答案(Array.prototype.map() 仅适用于 IE9+ 并且 lambda(箭头)函数不支持 IE):

AccountModel.findAll({
    where: {
        Age: {
            $gt : 18
        }
    },
    attributes: ['Name'],
    raw : true
})
.then(accounts => accounts.map(account => account.Name));

代码段(在 ie 中不起作用):

这是我用来证明概念的一个小片段。如果它不起作用,则您使用的是上面提到的一种不受支持的浏览器(无论如何您都不应该直接从浏览器进行数据库调用):

let objArray=[{key:1},{key:2},{key:3}];
console.log("Not IE friendly:");
console.log(objArray.map(obj => obj.key));
console.log("IE friendly (might even be ES3):");
let names = [];
for(let i=0 ; i<objArray.length ; i++){
    names[i] = objArray[i].key
}
console.log(names)

2020年解决方案

大家好,您可以轻松地进行纯“采摘”方法:

const someVariable = [
  ... ( await AccountModel.findAll({
    where: {
        Age: {
            $gt : 18
        }
    },
    attributes: ['Name'],
    raw : true
  })),
].map(account => account.Name);