如何在数组中找到相似值(数字)并合并相似值?
how to find Similar values(number) in array and the merge similars?
我有示例数组,我想在数组中找到重复(相似)的数字然后合并。
var arr = [{
'title': 'abc',
'number': 1
},{
'title': 'def',
'number': 1
},{
'title': 'ghi',
'number': 2
}];
然后合并一定要像
var arr = [{
'title': ['abc', 'def'],
'number': 1
},{
'title': 'ghi',
'number': 2
}];
我的意思是重复的标题必须合并为一个,重复的必须删除。
最简单的方法之一是使用唯一键将数据缩减为 object 以捕获常见数据:
var obj = arr.reduce(function (p, c) {
var key = c.number;
// if the object doesn't exist, create a new one
// and set it's value as a pre-filled object
p[key] = p[key] || { title: [], number: key };
// then add the title to the title array
p[key].title.push(c.title);
return p;
}, {});
然后使用 object 键上的 map
重新创建 object 数组:
var data = Object.keys(obj).map(function (el) {
return { title: obj[el].title, number: el };
});
不管里面有多少元素,这都会给你一个标题数组,这是正确的方法(见@thefourtheye 的评论)。
但是,如果您只想在标题数组中有两个或更多元素时才拥有一个数组,则可以稍微更改代码:
var data = Object.keys(obj).map(function (el) {
var title = obj[el].title;
return {
title: title.length === 1 ? title[0] : title,
number: el
};
});
这是一种使用临时对象的方法,该对象保存对数组的引用和结果数组本身。
具有相同 number
的重复 title
仅插入一次(如 { 'title': 'xxx', 'number': 42 }
)。
var arr = [{ 'title': 'xxx', 'number': 42 }, { 'title': 'xxx', 'number': 42 }, { 'title': 'abc', 'number': 1 }, { 'title': 'def', 'number': 1 }, { 'title': 'ghi', 'number': 2 }],
result = arr.reduce(function (r, b) {
if (b.number in r.o) {
if (!(b.title in r.o[b.number])) {
r.a[r.o[b.number].index].title.push(b.title);
r.o[b.number][b.title] = true;
}
return r;
}
r.o[b.number] = { index: r.a.push({ title: [b.title], number: b.number }) - 1 };
r.o[b.number][b.title] = true;
return r;
}, { o: {}, a: [] }).a;
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
此解决方案遍历元素,并过滤掉具有相同编号的第二个和后续元素,但在此之前将它们的标题添加到第一个匹配项。换句话说,它几乎完全符合您提出的 "algorithm",到
I mean duplicate's title must be merged into one and duplicate must be deleted.
array.filter(function(elt, idx) {
var number = elt.number;
var title = elt.title;
// Check if an element has a number that matches the current one.
function sameNumber(elt) { return number === elt.number; }
// Find the index of the first array element with the same number.
var first = findIndex(array, sameNumber);
// If this is the first, just pass it through the filter.
if (idx === first) return true;
// Otherwise, concatenate our title with the title of the first occurrence.
array[first].title = [].concat(array[first].title, title);
}
其中 findIndex
是(如果可用也可以使用 Array#findIndex
):
function findIndex(array, condition) {
for (var i = 0; i < array.length; i++) {
if (condition(array[i])) return i;
}
return -1;
}
如果您希望title
始终是一个数组,即使该数字只出现一次,则将相关行更改如下:
// If this is the first, just pass it through the filter.
if (idx === first) { elt.title = [elt.title]; return true; }
// Otherwise, concatenate our title with the title of the first occurrence.
array[first].title.push(title);
这避免了必须创建一些其他 object-like 数据表示,然后再转换回数组格式。
我有示例数组,我想在数组中找到重复(相似)的数字然后合并。
var arr = [{
'title': 'abc',
'number': 1
},{
'title': 'def',
'number': 1
},{
'title': 'ghi',
'number': 2
}];
然后合并一定要像
var arr = [{
'title': ['abc', 'def'],
'number': 1
},{
'title': 'ghi',
'number': 2
}];
我的意思是重复的标题必须合并为一个,重复的必须删除。
最简单的方法之一是使用唯一键将数据缩减为 object 以捕获常见数据:
var obj = arr.reduce(function (p, c) {
var key = c.number;
// if the object doesn't exist, create a new one
// and set it's value as a pre-filled object
p[key] = p[key] || { title: [], number: key };
// then add the title to the title array
p[key].title.push(c.title);
return p;
}, {});
然后使用 object 键上的 map
重新创建 object 数组:
var data = Object.keys(obj).map(function (el) {
return { title: obj[el].title, number: el };
});
不管里面有多少元素,这都会给你一个标题数组,这是正确的方法(见@thefourtheye 的评论)。
但是,如果您只想在标题数组中有两个或更多元素时才拥有一个数组,则可以稍微更改代码:
var data = Object.keys(obj).map(function (el) {
var title = obj[el].title;
return {
title: title.length === 1 ? title[0] : title,
number: el
};
});
这是一种使用临时对象的方法,该对象保存对数组的引用和结果数组本身。
具有相同 number
的重复 title
仅插入一次(如 { 'title': 'xxx', 'number': 42 }
)。
var arr = [{ 'title': 'xxx', 'number': 42 }, { 'title': 'xxx', 'number': 42 }, { 'title': 'abc', 'number': 1 }, { 'title': 'def', 'number': 1 }, { 'title': 'ghi', 'number': 2 }],
result = arr.reduce(function (r, b) {
if (b.number in r.o) {
if (!(b.title in r.o[b.number])) {
r.a[r.o[b.number].index].title.push(b.title);
r.o[b.number][b.title] = true;
}
return r;
}
r.o[b.number] = { index: r.a.push({ title: [b.title], number: b.number }) - 1 };
r.o[b.number][b.title] = true;
return r;
}, { o: {}, a: [] }).a;
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
此解决方案遍历元素,并过滤掉具有相同编号的第二个和后续元素,但在此之前将它们的标题添加到第一个匹配项。换句话说,它几乎完全符合您提出的 "algorithm",到
I mean duplicate's title must be merged into one and duplicate must be deleted.
array.filter(function(elt, idx) {
var number = elt.number;
var title = elt.title;
// Check if an element has a number that matches the current one.
function sameNumber(elt) { return number === elt.number; }
// Find the index of the first array element with the same number.
var first = findIndex(array, sameNumber);
// If this is the first, just pass it through the filter.
if (idx === first) return true;
// Otherwise, concatenate our title with the title of the first occurrence.
array[first].title = [].concat(array[first].title, title);
}
其中 findIndex
是(如果可用也可以使用 Array#findIndex
):
function findIndex(array, condition) {
for (var i = 0; i < array.length; i++) {
if (condition(array[i])) return i;
}
return -1;
}
如果您希望title
始终是一个数组,即使该数字只出现一次,则将相关行更改如下:
// If this is the first, just pass it through the filter.
if (idx === first) { elt.title = [elt.title]; return true; }
// Otherwise, concatenate our title with the title of the first occurrence.
array[first].title.push(title);
这避免了必须创建一些其他 object-like 数据表示,然后再转换回数组格式。