Вы можете заставить его работать со следующим Binding:
Binding="{Binding Path=.}
Но он не решит вашу проблему, потому что строки являются типичными, которые являются неизменяемыми, то есть вы не можете изменить ссылку на строку, с которой вы привязались ваш пользовательский интерфейс.
Итак, ваши мысли верны, вам нужно будет обернуть эти строки в объекты, использовать свойство path для привязки и передать эти объекты в ваш DataGrid.
public class StringWrapper
{
public string Value { get; set; }
}
Во-первых, в JavaScript обычно не рекомендуется перебирать массивы с помощью for ... in
. См. Почему используется & quot; для ... в & quot;
Итак, вы можете попробовать что-то вроде этого:
var groups = {};
for (var i = 0; i < myArray.length; i++) {
var groupName = myArray[i].group;
if (!groups[groupName]) {
groups[groupName] = [];
}
groups[groupName].push(myArray[i].color);
}
myArray = [];
for (var groupName in groups) {
myArray.push({group: groupName, color: groups[groupName]});
}
Использование промежуточного объекта groups
здесь помогает ускорить работу потому что он позволяет избежать циклов вложенности для поиска по массивам. Кроме того, поскольку groups
является объектом (а не массивом), итерация по нему с использованием for ... in
является подходящей.
Добавление
FWIW, если вы хотите избежать дублирования записей цвета в результирующих массивах вы можете добавить оператор if
над строкой groups[groupName].push(myArray[i].color);
, чтобы защитить от дубликатов. Используя jQuery, он будет выглядеть следующим образом:
if (!$.inArray(myArray[i].color, groups[groupName])) {
groups[groupName].push(myArray[i].color);
}
Без jQuery вы можете добавить функцию, которая выполняет ту же функцию, что и jQuery inArray
:
Array.prototype.contains = function(value) {
for (var i = 0; i < this.length; i++) {
if (this[i] === value)
return true;
}
return false;
}
, а затем используйте это следующим образом:
if (!groups[groupName].contains(myArray[i].color)) {
groups[groupName].push(myArray[i].color);
}
Обратите внимание, что в любом случае вы собираетесь немного замедлить работу из-за всей дополнительной итерации, поэтому, если вам не нужно избегать дублирования записей цвета в Я бы рекомендовал избегать этого дополнительного кода. Там
Начните с создания сопоставления имен групп со значениями. Затем преобразование в желаемый формат.
var myArray = [
{group: "one", color: "red"},
{group: "two", color: "blue"},
{group: "one", color: "green"},
{group: "one", color: "black"}
];
var group_to_values = myArray.reduce(function (obj, item) {
obj[item.group] = obj[item.group] || [];
obj[item.group].push(item.color);
return obj;
}, {});
var groups = Object.keys(group_to_values).map(function (key) {
return {group: key, color: group_to_values[key]};
});
var pre = document.createElement("pre");
pre.innerHTML = "groups:\n\n" + JSON.stringify(groups, null, 4);
document.body.appendChild(pre);
Использование методов экземпляра Array, таких как , уменьшает и карту дает вам мощные конструкции более высокого уровня, которые могут сэкономить вам много боли в ручном режиме.
groups = Object.entries(group_to_values).map(([group, color]) => ({ group, color }));
– a15n
12 July 2017 в 22:39
Object.keys
– William
2 August 2017 в 15:20
Используя методы Array reduce
и findIndex
, это может быть достигнуто.
var myArray = [{
group: "one",
color: "red"
}, {
group: "two",
color: "blue"
}, {
group: "one",
color: "green"
}, {
group: "one",
color: "black"
}];
var transformedArray = myArray.reduce((acc, arr) => {
var index = acc.findIndex(function(element) {
return element.group === arr.group;
});
if (index === -1) {
return acc.push({
group: arr.group,
color: [arr.color]
});
}
acc[index].color.push(arr.color);
return acc;
}, []);
console.log(transformedArray);
Используя функцию reduce
, массив является итератором, а новые значения сохраняются в параметре acc (accumulating)
. Чтобы проверить, существует ли объект с заданным group
, мы можем использовать функцию findIndex
.
Если findIndex()
возвращает -1, значение не существует, поэтому добавьте массив в acc
параметр.
Если findIndex()
возвращает индекс, то обновите index
с помощью значений arr
.
Эта версия использует преимущества того, что ключи объектов уникальны. Мы обрабатываем исходный массив и собираем цвета по группе в новом объекте. Затем создайте новые объекты из этой группы -> массив массивов цветов.
var myArray = [{
group: "one",
color: "red"
}, {
group: "two",
color: "blue"
}, {
group: "one",
color: "green"
}, {
group: "one",
color: "black"
}];
//new object with keys as group and
//color array as value
var newArray = {};
//iterate through each element of array
myArray.forEach(function(val) {
var curr = newArray[val.group]
//if array key doesnt exist, init with empty array
if (!curr) {
newArray[val.group] = [];
}
//append color to this key
newArray[val.group].push(val.color);
});
//remove elements from previous array
myArray.length = 0;
//replace elements with new objects made of
//key value pairs from our created object
for (var key in newArray) {
myArray.push({
'group': key,
'color': newArray[key]
});
}
Обратите внимание, что это не учитывает повторяющиеся цвета той же группы, поэтому возможно иметь несколько одинаковых цветов в массиве для одной группы.
Использовать метод lodash groupby
Создает объект, состоящий из ключей, сгенерированных из результатов запуска каждого элемента коллекции через iteratee. Порядок группируемых значений определяется порядком их возникновения в коллекции. Соответствующее значение каждой клавиши представляет собой массив элементов, ответственных за генерацию ключа. Итератор вызывается одним аргументом: (значение).
blockquote>Таким образом, с помощью lodash вы можете получить то, что хотите в одной строке. См. Ниже
let myArray = [ {group: "one", color: "red"}, {group: "two", color: "blue"}, {group: "one", color: "green"}, {group: "one", color: "black"}, ] let grouppedArray=_.groupBy(myArray,'group') console.log(grouppedArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Помимо данных подходов с двухпроходным подходом, вы можете выбрать один цикл, нажав группу, если будет найдена новая группа.
var array = [{ group: "one", color: "red" }, { group: "two", color: "blue" }, { group: "one", color: "green" }, { group: "one", color: "black" }],
groups = Object.create(null),
grouped = [];
array.forEach(function (o) {
if (!groups[o.group]) {
groups[o.group] = [];
grouped.push({ group: o.group, color: groups[o.group] });
}
groups[o.group].push(o.color);
});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Вы можете сделать что-то вроде этого:
function convert(items) {
var result = [];
items.forEach(function (element) {
var existingElement = result.filter(function (item) {
return item.group === element.group;
})[0];
if (existingElement) {
existingElement.color.push(element.color);
} else {
element.color = [element.color];
result.push(element);
}
});
return result;
}
var array = [{
id: "123",
name: "aaaaaaaa"
}, {
id: "123",
name: "aaaaaaaa"
}, {
id: '456',
name: 'bbbbbbbbbb'
}, {
id: '789',
name: 'ccccccccc'
}, {
id: '789',
name: 'ccccccccc'
}, {
id: '098',
name: 'dddddddddddd'
}];
//if you want to group this array
group(array, key) {
console.log(array);
let finalArray = [];
array.forEach(function(element) {
var newArray = [];
array.forEach(function(element1) {
if (element[key] == element1[key]) {
newArray.push(element)
}
});
if (!(finalArray.some(arrVal => newArray[0][key] == arrVal[0][key]))) {
finalArray.push(newArray);
}
});
return finalArray
}
//and call this function
groupArray(arr, key) {
console.log(this.group(arr, key))
}
Один из вариантов:
var res = myArray.reduce(function(groups, currentValue) {
if ( groups.indexOf(currentValue.group) === -1 ) {
groups.push(currentValue.group);
}
return groups;
}, []).map(function(group) {
return {
group: group,
color: myArray.filter(function(_el) {
return _el.group === group;
}).map(function(_el) { return _el.color; })
}
});
for
.
– Jan
28 July 2015 в 23:46
_myArray_. With var myArray = [ {group: "one", color: "red"}, {group: "two", color: "blue"}, {group: "one", color: "green"}, {group: "one", color: "black"}, {group: "one", color: "black"} ];
. Вы получитеmyArray[0].color = ["red", "green", "black", "black"]
– Lends 28 July 2015 в 23:32