function diff(data1, data2, key = n => n) {
const getKey = key instanceof Function ? key : n => n[key];
const keys = new Set(Array.from(data2, getKey));
const result = [];
for (const n of data1) {
if (!keys.has(getKey(n))) {
result.push(n);
}
}
return result;
}
// ваш случай
const result = diff(arr1, arr2, 'id');
// есть и другие варианты использования
diff(Array(10).keys(), Array(7).keys()) // [ 7, 8, 9 ]
diff('ABCDE', 'ace', n => n.toLowerCase()) // [ 'B', 'D' ]
state.checkboxes.map(n => n.id === action.id
? { ...n, active: !n.active }
: n
)
function onChange() {
document.querySelector('селектор элемента для вывода результата проверки').innerText = [
// здесь массив селекторов вида
// input[имя_атрибута1="значение1"][имя_атрибута2="значение2"]:checked
].every(n => document.querySelector(n))
? 'какой-то текст'
: 'какой-то другой текст';
}
onChange();
document.addEventListener('change', e => {
if (e.target.matches('input[type="radio"]')) {
onChange();
}
});
const priceObj = Object.fromEntries(price.map((n, i) => [ `ad${i}`, n.ad ]));
const priceObj = price
.map(Object.entries)
.reduce((acc, [[ k, v ]], i) => (acc[k + i] = v, acc), {});
const priceObj = {};
for (const [ i, n ] of price.entries()) {
for (const k in n) {
priceObj[k.concat(i)] = n[k];
break;
}
}
Object.entries(str.split('').reduce((acc, n) => (acc[n] = (acc[n] ?? 0) + 1, acc), {}))
[...[...str].reduce((acc, n) => acc.set(n, -~acc.get(n)), new Map)]
Object.values(str).sort().join('').match(/(.)\1*/g)?.map(n => [ n[0], n.length ]) ?? []
Array.from(new Set(str), n => [ n, str.split(n).length - 1 ])
computed: {
newTodoValid() {
return this.newTodo.length >= 10;
},
},
<input :class="newTodoValid ? 'valid' : 'not-valid'">
<button :disabled="!newTodoValid">
.valid {
border: 2px solid green;
}
.not-valid {
border: 2px solid red;
}
const result = Object.values(runs.reduce(
(acc, n) => (acc[n.projectId]?.description.push(n), acc),
Object.fromEntries(projects.map(n => [ n.id, { ...n, description: [] } ]))
));
const result = projects.map(function(n) {
return {
...n,
description: this[n.id] ?? [],
};
}, runs.reduce((acc, n) => ((acc[n.projectId] = acc[n.projectId] ?? []).push(n), acc), {}));
const result = projects.map(n => ({
...n,
description: runs.filter(m => m.projectId === n.id),
}));
const group = (arr, idKey, valKey) =>
Object.values(arr.reduce((acc, { [idKey]: id, [valKey]: val }) => (
(acc[id] = acc[id] ?? { [idKey]: id, [valKey]: [] })[valKey].push(val),
acc
), {}));
const groupedAddresses = useMemo(() => {
return group(addresses, 'city', 'address');
}, [ addresses ]);
<ul>
{groupedAddresses.map(n => (
<li>
<h3>{n.city}</h3>
<ul>{n.address.map(m => <li>{m}</li>)}</ul>
</li>
))}
</ul>
users.sort((a, b) => (a.age ?? Infinity) - (b.age ?? Infinity));
const sortedUsers = Object
.values(users.reduce((acc, n) => ((acc[n.age] = acc[n.age] ?? []).push(n), acc), {}))
.flat();
// или
const sorted = (arr, key) => arr
.map(n => [ n, key(n) ])
.sort((a, b) => a[1] - b[1])
.map(n => n[0]);
const sortedUsers = sorted(users, n => n.age ?? Infinity);
const unique = Object.values(arr.reduce((acc, n) => (acc[n.name] = n, acc), {}));
const names = unique.map(({ name }, i) => ({ id: -~i, name }));
const ages = unique.map((n, i) => ({ id: i + 1, age: n.age }));
const extractUnique = (arr, idKey, keys) =>
arr.reduce((acc, n) => {
if (!acc[1].has(n[idKey])) {
const id = acc[1].add(n[idKey]).size;
keys.forEach((k, i) => acc[0][i].push({ id, [k]: n[k] }));
}
return acc;
}, [ keys.map(() => []), new Set ])[0];
const [ names, ages ] = extractUnique(arr, 'name', [ 'name', 'age' ]);
<select id="city"></select>
<select id="warehouse"></select>
const citySelect = document.querySelector('#city');
const warehouseSelect = document.querySelector('#warehouse');
citySelect.addEventListener('change', function() {
updateSelectOptions(warehouseSelect, {
calledMethod: 'getWarehouses',
methodProperties: {
CityName: this.value,
},
});
});
updateSelectOptions(citySelect, {
calledMethod: 'getCities',
methodProperties: {
FindByString: '',
},
});
function updateSelectOptions(selectEl, queryData) {
fetch('https://api.novaposhta.ua/v2.0/json/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
modelName: 'Address',
apiKey: '',
...queryData,
}),
})
.then(r => r.json())
.then(r => selectEl.innerHTML = r.data
.map(n => `<option>${n.Description}</option>`)
.join('')
);
}
const includes = (a, b) => Object.entries(b).every(([ k, v ]) => Object.is(v, a[k]));
const check = (a, b) => Object.values(a).some(n => includes(n, b));
const result = check(parent, { a: '1', b: '1' });
if (localStorage.getItem('mediaObjViewSeen') === true) {
Ключи и значения всегда строки
data: () => ({
view: localStorage.getItem('view') || 'CardsView',
// ...
}),
watch: {
view: val => localStorage.setItem('view', val),
},
data: () => ({
views: [
{
name: 'CardsView',
btnClass: 'btn-left',
img: '...',
},
{
name: 'MediaObjView',
btnClass: 'btn-right',
img: '...',
},
],
// ...
}),
<button
v-for="n in views"
:class="[ n.btnClass, view === n.name ? 'btn-active' : '' ]"
@click="view = n.name"
>
<img :src="n.img">
</button>
view
в TweetPreview
, используете его значение как имя компонента:<component
:is="view"
:tweet="tweet"
/>