合并和重新排序两个对象数组
Merging and reordering two arrays of objects
我正在尝试弄清楚如何合并两个对象数组。这是我需要做的:
field
属性是每个对象的唯一标识
- 输出只需要
originalArray
中列出的对象
- 需要保持
localStorageArray
的顺序,注意之前的要求(顺序应该是:bar
、foo
、baz
)
- 输出需要包含来自
localStorageArray
的以下 属性 值:hidden
和 width
(field
是让步,因为它是标识符)
originalArray
的所有其他属性需要在输出中维护
这是我的怪癖:
outputArray.forEach(function(originalItem){
localStorageArray.forEach(function(localItem){
if(originalItem.field === localItem.field){
originalItem.hidden = localItem.hidden;
originalItem.width = localItem.width;
}
});
});
Full JS Fiddle
我能够获得所有属性,但我对如何根据 localStorageArray
重新排序有点迷茫。我首先想到在前一组 .forEach()
函数中这样做,但后来我认为不要弄乱 forEach
循环中的顺序,因为我认为这可能会弄乱一些事情。
对我的解决方案有什么建议吗?
这是我的数组:
var originalArray = [{
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "20px",
propA: "a",
propB: "b"
}, {
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "20%",
propC: "C"
}, {
field: "baz",
hidden: false,
sortable: true,
template: "<span>#=text#</span>",
int: 3
}];
var localStorageArray = [{
field: "bar",
hidden: false,
sortable: false,
width: "100px"
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px"
}, {
field: "boo",
hidden: true,
sortable: true,
template: "<div>Boo: #=text#</div>",
width: "200px"
}, {
field: "baz",
hidden: true,
template: "baz:#=text#",
width: "20px"
}];
这是我想要的输出:
var desiredArray = [{
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "100px",
propC: "C"
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px",
propA: "a",
propB: "b"
}, {
field: "baz",
hidden: true,
sortable: true,
template: "<span>#=text#</span>",
width: "20px",
int: 3
}];
检查此 fiddle:http://jsfiddle.net/j2u2hhk6/
你实际上可以这样做:
var outputArray = [];
localStorageArray.forEach(function(localItem){
originalArray.forEach(function(originalItem){
if(originalItem.field === localItem.field){
var item = JSON.parse(JSON.stringify(originalItem));
item.hidden = localItem.hidden;
item.width = localItem.width;
outputArray.push(item);
}
});
});
这里是一个使用 ES6 方法的例子。
/*global document, console, expect */
(function () {
'use strict';
var originalArray = [{
field: 'foo',
hidden: true,
sortable: false,
template: '<div>#=text#</div>',
width: '20px',
propA: 'a',
propB: 'b'
}, {
field: 'bar',
hidden: false,
sortable: false,
template: '',
width: '20%',
propC: 'C'
}, {
field: 'baz',
hidden: false,
sortable: true,
template: '<span>#=text#</span>',
int: 3
}],
localStorageArray = [{
field: 'bar',
hidden: false,
sortable: false,
width: '100px'
}, {
field: 'foo',
hidden: true,
sortable: false,
template: '<div>#=text#</div>',
width: '40px'
}, {
field: 'boo',
hidden: true,
sortable: true,
template: '<div>Boo: #=text#</div>',
width: '200px'
}, {
field: 'baz',
hidden: true,
template: 'baz:#=text#',
width: '20px'
}],
desiredArray = [{
field: 'bar',
hidden: false,
sortable: false,
template: '',
width: '100px',
propC: 'C'
}, {
field: 'foo',
hidden: true,
sortable: false,
template: '<div>#=text#</div>',
width: '40px',
propA: 'a',
propB: 'b'
}, {
field: 'baz',
hidden: true,
sortable: true,
template: '<span>#=text#</span>',
width: '20px',
int: 3
}],
outputArray = [],
pre = document.getElementById('out'),
equalField = function (originalElement) {
return originalElement.field === this.field;
};
localStorageArray.reduce(function (acc, localElement) {
var original = originalArray.find(equalField, localElement),
shallowCopy;
if (original) {
shallowCopy = Object.assign({}, original);
shallowCopy.hidden = localElement.hidden;
shallowCopy.width = localElement.width;
acc.push(shallowCopy);
}
return acc;
}, outputArray);
try {
expect(outputArray).to.eql(desiredArray);
pre.textContent = 'outputArray is equal to desiredArray\n\n';
} catch (e) {
console.error(e);
pre.textContent = 'outputArray is not equal to desiredArray\n\n';
}
pre.textContent += JSON.stringify(outputArray, null, 2);
}());
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.32.0/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
<pre id="out"></pre>
更新:根据您的新评论和数据,这可能是一个解决方案。
var originalArray = [{
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "20px",
propA: "a",
propB: "b"
}, {
field: "bee",
hidden: true,
sortable: false,
template: "=#text#",
int: 4
}, {
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "20%",
propC: "C"
}, {
field: "baz",
hidden: false,
sortable: true,
template: "<span>#=text#</span>",
int: 3
}],
localStorageArray = [{
field: "bar",
hidden: false,
sortable: false,
width: "100px"
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px"
}, {
field: "boo",
hidden: true,
sortable: true,
template: "<div>Boo: #=text#</div>",
width: "200px"
}, {
field: "baz",
hidden: true,
template: "baz:#=text#",
width: "20px"
}],
desiredArray = [{
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "100px",
propC: "C"
}, {
field: "bee",
hidden: true,
sortable: false,
template: "=#text#",
int: 4
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px",
propA: "a",
propB: "b"
}, {
field: "baz",
hidden: true,
sortable: true,
template: "<span>#=text#</span>",
width: "20px",
int: 3
}],
outputArray = [],
pre = document.getElementById('out'),
equalField = function (originalElement) {
return originalElement.field === this.field;
};
localStorageArray.reduce(function (acc, localElement) {
var original = originalArray.find(equalField, localElement),
shallowCopy;
if (original) {
shallowCopy = Object.assign({}, original);
shallowCopy.hidden = localElement.hidden;
shallowCopy.width = localElement.width;
acc.push(shallowCopy);
}
return acc;
}, outputArray);
originalArray.forEach(function (originalElement, index) {
if (!this.find(equalField, originalElement)) {
this.splice(index, 0, Object.assign({}, originalElement));
}
}, outputArray);
try {
expect(outputArray).to.eql(desiredArray);
pre.textContent = 'outputArray is equal to desiredArray\n\n';
} catch (e) {
console.error(e);
pre.textContent = 'outputArray is not equal to desiredArray\n\n';
}
pre.textContent += JSON.stringify(outputArray, null, 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.32.0/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
<pre id="out"></pre>
我正在尝试弄清楚如何合并两个对象数组。这是我需要做的:
field
属性是每个对象的唯一标识- 输出只需要
originalArray
中列出的对象
- 需要保持
localStorageArray
的顺序,注意之前的要求(顺序应该是:bar
、foo
、baz
) - 输出需要包含来自
localStorageArray
的以下 属性 值:hidden
和width
(field
是让步,因为它是标识符) originalArray
的所有其他属性需要在输出中维护
这是我的怪癖:
outputArray.forEach(function(originalItem){
localStorageArray.forEach(function(localItem){
if(originalItem.field === localItem.field){
originalItem.hidden = localItem.hidden;
originalItem.width = localItem.width;
}
});
});
Full JS Fiddle
我能够获得所有属性,但我对如何根据 localStorageArray
重新排序有点迷茫。我首先想到在前一组 .forEach()
函数中这样做,但后来我认为不要弄乱 forEach
循环中的顺序,因为我认为这可能会弄乱一些事情。
对我的解决方案有什么建议吗?
这是我的数组:
var originalArray = [{
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "20px",
propA: "a",
propB: "b"
}, {
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "20%",
propC: "C"
}, {
field: "baz",
hidden: false,
sortable: true,
template: "<span>#=text#</span>",
int: 3
}];
var localStorageArray = [{
field: "bar",
hidden: false,
sortable: false,
width: "100px"
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px"
}, {
field: "boo",
hidden: true,
sortable: true,
template: "<div>Boo: #=text#</div>",
width: "200px"
}, {
field: "baz",
hidden: true,
template: "baz:#=text#",
width: "20px"
}];
这是我想要的输出:
var desiredArray = [{
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "100px",
propC: "C"
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px",
propA: "a",
propB: "b"
}, {
field: "baz",
hidden: true,
sortable: true,
template: "<span>#=text#</span>",
width: "20px",
int: 3
}];
检查此 fiddle:http://jsfiddle.net/j2u2hhk6/
你实际上可以这样做:
var outputArray = [];
localStorageArray.forEach(function(localItem){
originalArray.forEach(function(originalItem){
if(originalItem.field === localItem.field){
var item = JSON.parse(JSON.stringify(originalItem));
item.hidden = localItem.hidden;
item.width = localItem.width;
outputArray.push(item);
}
});
});
这里是一个使用 ES6 方法的例子。
/*global document, console, expect */
(function () {
'use strict';
var originalArray = [{
field: 'foo',
hidden: true,
sortable: false,
template: '<div>#=text#</div>',
width: '20px',
propA: 'a',
propB: 'b'
}, {
field: 'bar',
hidden: false,
sortable: false,
template: '',
width: '20%',
propC: 'C'
}, {
field: 'baz',
hidden: false,
sortable: true,
template: '<span>#=text#</span>',
int: 3
}],
localStorageArray = [{
field: 'bar',
hidden: false,
sortable: false,
width: '100px'
}, {
field: 'foo',
hidden: true,
sortable: false,
template: '<div>#=text#</div>',
width: '40px'
}, {
field: 'boo',
hidden: true,
sortable: true,
template: '<div>Boo: #=text#</div>',
width: '200px'
}, {
field: 'baz',
hidden: true,
template: 'baz:#=text#',
width: '20px'
}],
desiredArray = [{
field: 'bar',
hidden: false,
sortable: false,
template: '',
width: '100px',
propC: 'C'
}, {
field: 'foo',
hidden: true,
sortable: false,
template: '<div>#=text#</div>',
width: '40px',
propA: 'a',
propB: 'b'
}, {
field: 'baz',
hidden: true,
sortable: true,
template: '<span>#=text#</span>',
width: '20px',
int: 3
}],
outputArray = [],
pre = document.getElementById('out'),
equalField = function (originalElement) {
return originalElement.field === this.field;
};
localStorageArray.reduce(function (acc, localElement) {
var original = originalArray.find(equalField, localElement),
shallowCopy;
if (original) {
shallowCopy = Object.assign({}, original);
shallowCopy.hidden = localElement.hidden;
shallowCopy.width = localElement.width;
acc.push(shallowCopy);
}
return acc;
}, outputArray);
try {
expect(outputArray).to.eql(desiredArray);
pre.textContent = 'outputArray is equal to desiredArray\n\n';
} catch (e) {
console.error(e);
pre.textContent = 'outputArray is not equal to desiredArray\n\n';
}
pre.textContent += JSON.stringify(outputArray, null, 2);
}());
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.32.0/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
<pre id="out"></pre>
更新:根据您的新评论和数据,这可能是一个解决方案。
var originalArray = [{
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "20px",
propA: "a",
propB: "b"
}, {
field: "bee",
hidden: true,
sortable: false,
template: "=#text#",
int: 4
}, {
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "20%",
propC: "C"
}, {
field: "baz",
hidden: false,
sortable: true,
template: "<span>#=text#</span>",
int: 3
}],
localStorageArray = [{
field: "bar",
hidden: false,
sortable: false,
width: "100px"
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px"
}, {
field: "boo",
hidden: true,
sortable: true,
template: "<div>Boo: #=text#</div>",
width: "200px"
}, {
field: "baz",
hidden: true,
template: "baz:#=text#",
width: "20px"
}],
desiredArray = [{
field: "bar",
hidden: false,
sortable: false,
template: "",
width: "100px",
propC: "C"
}, {
field: "bee",
hidden: true,
sortable: false,
template: "=#text#",
int: 4
}, {
field: "foo",
hidden: true,
sortable: false,
template: "<div>#=text#</div>",
width: "40px",
propA: "a",
propB: "b"
}, {
field: "baz",
hidden: true,
sortable: true,
template: "<span>#=text#</span>",
width: "20px",
int: 3
}],
outputArray = [],
pre = document.getElementById('out'),
equalField = function (originalElement) {
return originalElement.field === this.field;
};
localStorageArray.reduce(function (acc, localElement) {
var original = originalArray.find(equalField, localElement),
shallowCopy;
if (original) {
shallowCopy = Object.assign({}, original);
shallowCopy.hidden = localElement.hidden;
shallowCopy.width = localElement.width;
acc.push(shallowCopy);
}
return acc;
}, outputArray);
originalArray.forEach(function (originalElement, index) {
if (!this.find(equalField, originalElement)) {
this.splice(index, 0, Object.assign({}, originalElement));
}
}, outputArray);
try {
expect(outputArray).to.eql(desiredArray);
pre.textContent = 'outputArray is equal to desiredArray\n\n';
} catch (e) {
console.error(e);
pre.textContent = 'outputArray is not equal to desiredArray\n\n';
}
pre.textContent += JSON.stringify(outputArray, null, 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.32.0/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
<pre id="out"></pre>