Reputation: 229
I have a simple question. Before I have look around, but the answers I find, was mostly for another situation.
I have two arrays with css-properties
old=['font-size: 12px;','color: 12px;','border-left: 1px solid red;'];
new=['font-size: 20px;','border-left: 1px solid green;','left:20px;'];
How can I combine this both arrays to have at the end an array which contains only unique styles with the properties from the "new" array if there is something change to the old ones?
In the example above, I want to have this result
result=['font-size: 20px;','color: 12px;','border-left: 1px solid green;','left:20px;'];
At the first time, I try to make a loop through the old elements, split the items at the ":" but then I see a problem about the names of the styles. If I check if "left" is inside a string it will return true on "left" but also on every other style-names which contains "left" for example margin-left, padding-left...
How I can solve it in the easiest way?
Thanks a lot.
Upvotes: 0
Views: 63
Reputation: 13963
Use can use Object.Values()
, Array.reduce()
and String.match()
:
const css1 = ['font-size: 12px;','color: 12px;','border-left: 1px solid red;'];
const css2 = ['font-size: 20px;','border-left: 1px solid green;','left:20px;'];
const merged =
Object.values(
[...css1, ...css2].reduce(
(acc, x) => (acc[x.match(/(.*)\s*:/)[1]] = x, acc), {}));
console.log(merged)
Upvotes: 1
Reputation: 350272
When you have support for Object.fromEntries
, then:
function mergeCss(...args) {
return Object.entries(
Object.fromEntries(args.flatMap(a => a.map(a => a.match(/^[^:\s]*|[^:\s].+$/g))))
).map(arg => arg.join(": "));
}
const result = mergeCss(['font-size: 12px;','color: 12px;','border-left: 1px solid red;'],
['font-size: 20px;','border-left: 1px solid green;','left:20px;']);
console.log(result);
You can pass more than two arrays to the above function.
Polyfill for Object.fromEntries
:
Object.fromEntries = arr =>
Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));
Upvotes: 2
Reputation: 370759
You might create a single array from the two (with the new items at the end) then reduce
into an object indexed by the substring that comes before the :
in the strings, and then get the object's entries:
const old = ['font-size: 12px;', 'color: 12px;', 'border-left: 1px solid red;'];
const newArr = ['font-size: 20px;', 'border-left: 1px solid green;', 'left:20px;'];
const resultObj = [...old, ...newArr].reduce((a, str) => {
const [key, val] = str.split(/: ?/);
a[key] = val;
return a;
}, {});
const result = Object.entries(resultObj).map(([key, value]) => `${key}: ${value}`);
console.log(result);
Note that new
is a reserved word - it can't be a variable name.
Upvotes: 5