我有一个如下所示的数据集:
[
[a, 10],
[b, 20],
[c, 30],
[d, 40],
["err", NaN],
[a, "foo"],
[b, "foo2"],
[c, "foo3"],
[f, "foo4"]
]
我想要映射每个数组的第一个对象,如果它重复设置为这样,如果之前没有显示填充空值:
[a, 10, "foo"],
[b, 20, "foo2"],
[c, 30, "foo3"],
[d, 40, null ],
[f, null, "foo4"]
我使用的是lodash,但我是noob。 任何想法如何接近真的很感激。
答案 0 :(得分:0)
您可以使用Array.prototype.reduce执行此操作。您需要获取数组的第一个元素,如果是第一次遇到它,则将其存储在索引及其在结果数组中的位置。然后将数组的副本添加到结果数组中。
如果您之前看过索引,只需将值附加到结果数组即可。 E.g。
// First elements are changed to strings for simplicity
var data = [
['a', 10],
['b', 20],
['c', 30],
['d', 40],
['err', NaN],
['a', "foo"],
['b', "foo2"],
['c', "foo3"],
['f', "foo4"]
];
var result = data.reduce(function(acc, arr){
// Use first element of array as a key. If not seen before, add
// to index object with its index in the data array.
// Then append a copy of the data array.
if (!acc.index.hasOwnProperty(arr[0])) {
acc.index[arr[0]] = acc.data.length;
acc.data.push(arr.slice());
// Otherwise, just append the value to appropriate array in data
} else {
acc.data[acc.index[arr[0]]].push(arr[1]);
}
return acc;
// Required output is in data property
}, {index:{}, data:[]}).data;
console.log(result);
为简单起见,我已将变量更改为字符串。只需确保每个变量的值在字符串化时都是唯一的,并且适合作为对象属性,否则您需要使用Map。
这可能会更加简洁,存在混淆的风险。
答案 1 :(得分:0)
使用lodash
启动一个lodash的链。使用_.groupBy()
通过第一个索引将数组收集到一个组中。使用_.map()
迭代组,初始化包含键(0索引)和null
的项目。迭代组项,并获取数组的第二个值。通过检查数字是否为数字(_.isNumber
)将值插入正确的位置:
var arr = [["a",10],["b",20],["c",30],["d",40],["err",null],["a","foo"],["b","foo2"],["c","foo3"],["f","foo4"]];
var result = _(arr) // start a chain
.groupBy('0') // group by index 0
.map(function(group, key) { // map the groups
var item = [key, null, null]; // init an item
// iterate the group
group.forEach(function(s) {
item[_.isNumber(s[1]) ? 1 : 2] = s[1]; // add the number or the string to the right place
});
return item;
})
.value(); // get the chain value
console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
使用ES6
Reduce数组到ES6 Map。对于每个项目,检查它是否存在于地图中,如果不存在,则添加if if not init包含密钥(0索引)和null
s的项目。如果值为数字,则将其放在索引1中;如果不是,则将值放在2。将地图values iterator和spread恢复为数组:
const arr = [["a",10],["b",20],["c",30],["d",40],["err",null],["a","foo"],["b","foo2"],["c","foo3"],["f","foo4"]];
const result = [...arr.reduce((m, [key, value]) => {
// if item doesn't exist in the Map, create a new item
m.has(key) || m.set(key, [key, null, null]);
// get the item from the map, and set the new value in the right place
m.get(key)[typeof value === 'number' ? 1 : 2] = value;
return m;
}, new Map()).values()]; // get the Map's value iterator and spread to an array
console.log(result);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;