我正在尝试操作此示例对象数组。
[ { name: 'John Wilson',
id: 123,
classes: ['java', 'c++']},
{ name: 'John Wilson',
id: 123,
classes: 'uml'},
{ name: 'Jane Smith',
id: 321,
classes: 'c++'} ]
我需要做的是合并具有相同“id”的对象,连接“类”并保留一个“名称”。
结果应为:
[ { name: 'John Wilson',
id: 123,
classes: ['java', 'c++', 'uml']},
{ name: 'Jane Smith',
id: 321,
classes: 'c++'} ]
我尝试使用.merge,但它不会连接'classes'中的值,它只保留最后一个相等对象的值。
使用lodash最简单的方法是什么?
答案 0 :(得分:3)
您正在寻找的功能是_.uniqWith
,有一个特殊的转折,我会在一分钟内解释。
_.uniqWith
与_.uniq
非常相似,因为它生成一个唯一的数组,但它允许您传递自己的自定义比较器函数,该函数将被调用以确定什么算作“相等”。 / p>
Sane程序员会明白这个比较器应该是无副作用的。这段代码的工作方式是破坏该规则,并使用在幕后做额外魔术的比较功能。但是,这会产生非常简洁的代码,无论您的数组中有多少这些对象都可以使用,所以我觉得违规是合理的。
我将比较器函数命名为compareAndMerge
,以免隐藏其不纯的性质。它将合并两个classes
数组并更新两个对象的相关属性,但前提是它们的id
值相同。
function merge(people) {
return _.uniqWith(people, compareAndMerge)
}
function compareAndMerge(first, second) {
if (first.id === second.id) {
first.classes = second.classes = [].concat(first.classes, second.classes)
return true
}
return false
}
var people = [{
name: 'John Wilson',
id: 123,
classes: ['java', 'c++']
}, {
name: 'John Wilson',
id: 123,
classes: 'uml'
}, {
name: 'Jane Smith',
id: 321,
classes: 'c++'
}]
console.log(merge(people))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
旁白:您在原始classes
列表周围缺少方括号。我确保上面的代码不关心classes
属性是否包含单个字符串或字符串数组,以防万一。
答案 1 :(得分:1)
使用ES6,您可以使用Map
来保存唯一值,Array#reduce
来填充它,spread operator和Map#values
将其转换回数组:
const arr = [{"name":"John Wilson","id":123,"classes":["java","c++"]},{"name":"John Wilson","id":123,"classes":"uml"},{"name":"Jane Smith","id":321,"classes":"c++"}];
const result = [...arr.reduce((hash, { id, name, classes }) => {
const current = hash.get(id) || { id, name, classes: [] };
classes && (current.classes = current.classes.concat(classes));
return hash.set(id, current);
}, new Map).values()];
console.log(result);
&#13;
答案 2 :(得分:0)
不确定使用lodash ...这是使用普通JS的方法:
textField(_:shouldChangeCharactersIn:replacementString:)
答案 3 :(得分:0)
使用_.mergeWith
设置合并自定义程序
_.reduce(data, function(result, item) {
item = _.mergeWith(
item,
_.find(result, {id: item.id}),
function(val, addVal) {
return _.isArray(val) ? _.concat(val, addVal) : val;
});
result = _.reject(result, {id: item.id})
return _.concat(result, item);
}, []);
答案 4 :(得分:0)
以下算法不是最好的算法,但至少我知道它的作用: - )
library(lubridate)
my_date <- "Thu, 21 Jan 2012 04:59:00 -0000"
# Get it into date format
my_date <- dmy_hms(my_date)
# Use convenience functions to set up the columns you wanted
data.frame(day=day(my_date), month=month(my_date), year=year(my_date),
timestamp = my_date)
&#13;
day month year timestamp
1 21 1 2012 2012-01-21 04:59:00
&#13;