将员工数组转换为字典
Convert array of employees to Dictionary
所以我正在使用 LinqJS 库来实现以下目标:
var allEmployees = [
{
"Id": 1374,
"FirstName": "John",
"LastName": "Doe"
},
{
"Id": 1375,
"FirstName": "Jane",
"LastName": "Doe"
}
];
var employeeDictionary = Enumerable.from(allEmployees).toDictionary("$.Id", "$.FirstName+' '+$.LastName").toEnumerable().toArray();
将employeeDictionary
序列化为JSON时,我得到以下格式:
[
{
"key": 1374,
"value": "John Doe"
},
{
"key": 1375,
"value": "Jane Doe"
}
]
我不希望我的数据采用这种格式,我希望采用这种格式:
{
"1374": "John Doe",
"1375": "Jane Doe"
}
我在 PHP 中使用 YaLinqo 写了类似的东西,它给了我需要的结果:
echo json_encode(from($employees)->toDictionary('$v["Id"]', '$v["FirstName"]." ".$v["LastName"]')->toArray());
但是,我希望能够在我的 JavaScript 中实现这一点。
您可以使用 reduce
来实现:
employeeDictionary.reduce((acc, employee) => {
acc[employee.key] = employee.value;
return acc
}, {})
或使用对象传播的较短版本:
employeeDictionary.reduce((acc, employee) => ({
...acc,
[employee.key]: employee.value
}), {})
我认为您将对象数组与字典混淆了。我在下面包含了两个版本以显示差异。
您想对数据做的是映射它,而不是减少它。
let allEmployees = [
{ "Id": 1374, "FirstName": "John", "LastName": "Doe" },
{ "Id": 1375, "FirstName": "Jane", "LastName": "Doe" }
];
let defaultOptions = {
keyField: 'Id',
valueFn: (emp) => `${emp['FirstName']} ${emp['LastName']}`
};
console.log('Dictionary', toDictionary(allEmployees, defaultOptions));
console.log('Pairs', toPairs(allEmployees, defaultOptions));
function toDictionary(list, options) {
let opts = Object.assign({ keyField: 'key', valueField: 'value' }, options);
return list.reduce((dict, item) => (Object.assign(dict, {
[item[opts.keyField]] : opts.valueFn ? opts.valueFn(item) : item[opts.valueField]
})), {});
}
function toPairs(list, options) {
let opts = Object.assign({ keyField: 'key', valueField: 'value' }, options);
return list.map((item) => ({
key : item[opts.keyField],
value : opts.valueFn ? opts.valueFn(item) : item[opts.valueField]
}));
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
这是一个列表包装器 class。
class ListWrapper {
constructor(list, options) {
this.list = list;
this.keyField = options.keyField || 'key'
this.valueField = options.valueField || 'value'
this.valueFn = options.valueFn /* optional */
}
toPairs() {
return this.list.map(e=>({key:e[this.keyField],value:this.valueFn?this.valueFn(e):e[this.valueField]}));
}
toDictionary() {
return this.list.reduce((d,e)=>(Object.assign(d,{[e[this.keyField]]:this.valueFn?this.valueFn(e):e[this.valueField]})),{});
}
}
let allEmployees = [
{ "Id": 1374, "FirstName": "John", "LastName": "Doe" },
{ "Id": 1375, "FirstName": "Jane", "LastName": "Doe" }
];
let listWrapper = new ListWrapper(allEmployees, {
keyField: 'Id',
valueFn: (emp) => `${emp['FirstName']} ${emp['LastName']}`
});
console.log('Dictionary', listWrapper.toDictionary());
console.log('Pairs', listWrapper.toPairs());
.as-console-wrapper { top: 0; max-height: 100% !important; }
在JavaScript中,数组是严格的始终是数字索引结构。所以,.toArray
遵守这一点。在 PHP 中,数组更接近于 JavaScript 认为的普通对象。
如果使用 this LINQ JavaScript library
您可以使用 .toObject
方法生成您格式的对象 - 您需要传入两个函数 - 一个键选择器和一个值选择器,以便使用正确的数据构建对象:
var allEmployees = [
{
"Id": 1374,
"FirstName": "John",
"LastName": "Doe"
},
{
"Id": 1375,
"FirstName": "Jane",
"LastName": "Doe"
}
];
var employeeDictionary = Enumerable.from(allEmployees)
.toDictionary("$.Id", "$.FirstName+' '+$.LastName")
.toEnumerable()
.toObject(entry => entry.key, entry => entry.value);
/* output:
{
"1374": "John Doe",
"1375": "Jane Doe"
}
*/
使用解构,key/value 选择器可以转换为:
.toObject(({key}) => key, ({value}) => value);
如果使用this library for LINQ operations,则需要稍微更改语法:
var allEmployees = [
{
"Id": 1374,
"FirstName": "John",
"LastName": "Doe"
},
{
"Id": 1375,
"FirstName": "Jane",
"LastName": "Doe"
}
];
var employeeDictionary = Enumerable.From(allEmployees)
.ToDictionary("$.Id", "$.FirstName+' '+$.LastName")
.ToEnumerable()
.ToObject("$.Key", "$.Value");
/* output:
{
"1374": "John Doe",
"1375": "Jane Doe"
}
*/
一个简短的 linq 版本
var allEmployees = [{ Id: 1374, FirstName: "John", LastName: "Doe" }, { Id: 1375, FirstName: "Jane", LastName: "Doe" }],
employeeDictionary = Enumerable.From(allEmployees)
.Select("$ => { key: $.Id, value: $.FirstName + ' ' + $.LastName }")
.ToObject("$.key", "$.value");
console.log(employeeDictionary);
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
具有解构和 Object.fromEntries
的简短方法。
var allEmployees = [{ Id: 1374, FirstName: "John", LastName: "Doe" }, { Id: 1375, FirstName: "Jane", LastName: "Doe" }],
employeeDictionary = Object.fromEntries(
allEmployees.map(({ Id, FirstName, LastName }) =>
[Id, [FirstName, LastName].join(' ')])
);
console.log(employeeDictionary);
所以我正在使用 LinqJS 库来实现以下目标:
var allEmployees = [
{
"Id": 1374,
"FirstName": "John",
"LastName": "Doe"
},
{
"Id": 1375,
"FirstName": "Jane",
"LastName": "Doe"
}
];
var employeeDictionary = Enumerable.from(allEmployees).toDictionary("$.Id", "$.FirstName+' '+$.LastName").toEnumerable().toArray();
将employeeDictionary
序列化为JSON时,我得到以下格式:
[
{
"key": 1374,
"value": "John Doe"
},
{
"key": 1375,
"value": "Jane Doe"
}
]
我不希望我的数据采用这种格式,我希望采用这种格式:
{
"1374": "John Doe",
"1375": "Jane Doe"
}
我在 PHP 中使用 YaLinqo 写了类似的东西,它给了我需要的结果:
echo json_encode(from($employees)->toDictionary('$v["Id"]', '$v["FirstName"]." ".$v["LastName"]')->toArray());
但是,我希望能够在我的 JavaScript 中实现这一点。
您可以使用 reduce
来实现:
employeeDictionary.reduce((acc, employee) => {
acc[employee.key] = employee.value;
return acc
}, {})
或使用对象传播的较短版本:
employeeDictionary.reduce((acc, employee) => ({
...acc,
[employee.key]: employee.value
}), {})
我认为您将对象数组与字典混淆了。我在下面包含了两个版本以显示差异。
您想对数据做的是映射它,而不是减少它。
let allEmployees = [
{ "Id": 1374, "FirstName": "John", "LastName": "Doe" },
{ "Id": 1375, "FirstName": "Jane", "LastName": "Doe" }
];
let defaultOptions = {
keyField: 'Id',
valueFn: (emp) => `${emp['FirstName']} ${emp['LastName']}`
};
console.log('Dictionary', toDictionary(allEmployees, defaultOptions));
console.log('Pairs', toPairs(allEmployees, defaultOptions));
function toDictionary(list, options) {
let opts = Object.assign({ keyField: 'key', valueField: 'value' }, options);
return list.reduce((dict, item) => (Object.assign(dict, {
[item[opts.keyField]] : opts.valueFn ? opts.valueFn(item) : item[opts.valueField]
})), {});
}
function toPairs(list, options) {
let opts = Object.assign({ keyField: 'key', valueField: 'value' }, options);
return list.map((item) => ({
key : item[opts.keyField],
value : opts.valueFn ? opts.valueFn(item) : item[opts.valueField]
}));
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
这是一个列表包装器 class。
class ListWrapper {
constructor(list, options) {
this.list = list;
this.keyField = options.keyField || 'key'
this.valueField = options.valueField || 'value'
this.valueFn = options.valueFn /* optional */
}
toPairs() {
return this.list.map(e=>({key:e[this.keyField],value:this.valueFn?this.valueFn(e):e[this.valueField]}));
}
toDictionary() {
return this.list.reduce((d,e)=>(Object.assign(d,{[e[this.keyField]]:this.valueFn?this.valueFn(e):e[this.valueField]})),{});
}
}
let allEmployees = [
{ "Id": 1374, "FirstName": "John", "LastName": "Doe" },
{ "Id": 1375, "FirstName": "Jane", "LastName": "Doe" }
];
let listWrapper = new ListWrapper(allEmployees, {
keyField: 'Id',
valueFn: (emp) => `${emp['FirstName']} ${emp['LastName']}`
});
console.log('Dictionary', listWrapper.toDictionary());
console.log('Pairs', listWrapper.toPairs());
.as-console-wrapper { top: 0; max-height: 100% !important; }
在JavaScript中,数组是严格的始终是数字索引结构。所以,.toArray
遵守这一点。在 PHP 中,数组更接近于 JavaScript 认为的普通对象。
如果使用 this LINQ JavaScript library
您可以使用 .toObject
方法生成您格式的对象 - 您需要传入两个函数 - 一个键选择器和一个值选择器,以便使用正确的数据构建对象:
var allEmployees = [
{
"Id": 1374,
"FirstName": "John",
"LastName": "Doe"
},
{
"Id": 1375,
"FirstName": "Jane",
"LastName": "Doe"
}
];
var employeeDictionary = Enumerable.from(allEmployees)
.toDictionary("$.Id", "$.FirstName+' '+$.LastName")
.toEnumerable()
.toObject(entry => entry.key, entry => entry.value);
/* output:
{
"1374": "John Doe",
"1375": "Jane Doe"
}
*/
使用解构,key/value 选择器可以转换为:
.toObject(({key}) => key, ({value}) => value);
如果使用this library for LINQ operations,则需要稍微更改语法:
var allEmployees = [
{
"Id": 1374,
"FirstName": "John",
"LastName": "Doe"
},
{
"Id": 1375,
"FirstName": "Jane",
"LastName": "Doe"
}
];
var employeeDictionary = Enumerable.From(allEmployees)
.ToDictionary("$.Id", "$.FirstName+' '+$.LastName")
.ToEnumerable()
.ToObject("$.Key", "$.Value");
/* output:
{
"1374": "John Doe",
"1375": "Jane Doe"
}
*/
一个简短的 linq 版本
var allEmployees = [{ Id: 1374, FirstName: "John", LastName: "Doe" }, { Id: 1375, FirstName: "Jane", LastName: "Doe" }],
employeeDictionary = Enumerable.From(allEmployees)
.Select("$ => { key: $.Id, value: $.FirstName + ' ' + $.LastName }")
.ToObject("$.key", "$.value");
console.log(employeeDictionary);
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
具有解构和 Object.fromEntries
的简短方法。
var allEmployees = [{ Id: 1374, FirstName: "John", LastName: "Doe" }, { Id: 1375, FirstName: "Jane", LastName: "Doe" }],
employeeDictionary = Object.fromEntries(
allEmployees.map(({ Id, FirstName, LastName }) =>
[Id, [FirstName, LastName].join(' ')])
);
console.log(employeeDictionary);