How to append to a nested list inside a list of dictionaries? - python-3.8

I am aware that this question has already been answered in the past but I am not able to generalize solutions to my problem, probably because I don't quite understand the underlying reason for this behaviour.
I have the following list:
matches = [
{'name': 'gm1', 'odds': {'full time': {'3way': []}}},
{'name': 'gm2', 'odds': {'full time': {'3way': []}}},
{'name': 'gm2', 'odds': {'full time': {'3way': []}}},
]
When I run:
for match in matches:
match['odds']['full time']['3way'].append({'match_index': matches.index(match)})
I expect to get:
[{'name': 'gm1', 'odds': {'full time': {'3way': [{'match_index': 0}]}}},
{'name': 'gm2', 'odds': {'full time': {'3way': [{'match_index': 1}]}}},
{'name': 'gm2', 'odds': {'full time': {'3way': [{'match_index': 2}]}}}]
and I am getting:
[{'name': 'gm1', 'odds': {'full time': {'3way': [{'match_index': 0}, {'match_index': 1}, {'match_index': 2}]}}},
{'name': 'gm2', 'odds': {'full time': {'3way': [{'match_index': 0}, {'match_index': 1}, {'match_index': 2}]}}},
{'name': 'gm2', 'odds': {'full time': {'3way': [{'match_index': 0}, {'match_index': 1}, {'match_index': 2}]}}}]
To add to the confusion this works as expected if I manually generate the list in my IDE but it produces unwanted results when the same list is loaded from a file.

I don't know if this is the issue, but you did not add commas to separate the elements in the matches list:
matches=[{'name': 'gm1', 'odds': {'full time': {'3way': []}}},{'name': 'gm2', 'odds': {'full time': {'3way': []}}},{'name': 'gm3', 'odds': {'full time': {'3way': []}}}]
After I have run you for I got correct result:
>>> for match in matches:
... match['odds']['full time']['3way'].append({'index': matches.index(match)})
Output:
>>> matches
[{'name': 'gm1', 'odds': {'full time': {'3way': [{'index': 0}]}}}, {'name': 'gm2', 'odds': {'full time': {'3way': [{'index': 1}]}}}, {'name': 'gm3', 'odds': {'full time': {'3way': [{'index': 2}]}}}]

Related

How to bind two dimensional data value to checkbox v-modal in buefy table?

I have one array which is in below format.
let tableData = [
{
'id': 123,
'subArray': [
{ 'subId': 'ABC123', 'name': 'subElement1', 'ischecked': true },
{ 'subId': 'DEF123', 'name': 'subElement11', 'ischecked': false }
]
},
{
'id': 456,
'subArray': [
{ 'subId': 'ABC456', 'name': 'subElement2', 'ischecked': true },
{ 'subId': 'DEF456', 'name': 'subElement22', 'ischecked': true }
]
},
{
'id': 789,
'subArray': [
{ 'subId': 'ABC789', 'name': 'subElement3', 'ischecked': false },
{ 'subId': 'DEF789', 'name': 'subElement33', 'ischecked': true }
]
},
{
'id': 121,
'subArray': [
{ 'subId': 'ABC012', 'name': 'subElement4', 'ischecked': false },
{ 'subId': 'DEF012', 'name': 'subElement44', 'ischecked': true }
]
}
]
I am using Buefy table to render the data in below way.
<b-table :data="tableData">
<template slot-scope="props">
<b-table-column label="ID" field="id"> {{ props.row.id }}</b-table-column>
<b-table-column label="SubArray" field="subArray">
<span v-for="sub in props.row.subArray" :key="sub.subId">
<b-checkbox v-model="sub.isChecked">{{ sub.name }}</b-checkbox>
</span>
</b-table-column>
</template>
</b-table>
Problem: When i check any of the checkbox, it will show the checkbox Checked just for which we clicked, but the 'isChecked' value for all row in array is updated to "True".
Example: If i check the checkbox for "subElement22", then subElement11, subElement33 and subElement44 will also update.
Expected: When i click any checkbox, value related to just that row should be updated not other.
How can i bind v-modal ?
Thanks.
I am not sure if this will solve your problem because you didn't share all your code. Can you please try this:
<div v-for="sub in tableData" :key="sub.subId">
<div v-for="subsub in sub.subArray" :key="subsub.id">
<input type="checkbox" v-model="subsub.isChecked"> {{subsub.name}}
</div>
</div>
What I am doing here creating 2 for loops. First one is for the tableData array and other is for subArrays. With this code all checkboxes act just like you want.

Handling data from option select forms in Vue

I have this select form:
<div class="control">
<div class="select">
<select v-model="chart.traces">
<option v-for="option in options" v- bind:value="option.value">
{{ option.text }}
</option>
</select>
</div>
</div>
Which gets data in the component:
data() {
return {
options:[
{text: "Financial Condition", value: [ {
x: [1, 2, 3, 4],
y: [10, 15, 13, 17],
mode: 'markers',
type: 'scatter',
name: 'Companies'
}, {
x: [5],
y: [8],
mode: 'markers',
type: 'scatter',
name: 'Checked'
}
]},
{text: "Ebitda", value: [ {
x: [2, 1, 3, 6],
y: [11, 12, 12, 17],
mode: 'markers',
type: 'scatter',
name: 'Companies'
}]
}
]
Now I need to push this data depends on what is selected to the another data object inside the component:
traces: []
However somehow the traces object is not being populated based on what is selected.
Here is Codepen where you can check what is happening:
Codepen
There is a typo there : v- bind:value="option.value".
It should be like that v-bind:value="option.value"
<div class="control">
<div class="select">
<select v-model="chart.traces">
<option v-for="option in options" v-bind:value="option.value">{{ option.text }}</option>
</select>
</div>
</div>

Get searched results of vuetify's v-autocomplete

See this codepen:
https://codepen.io/anon/pen/gNOGmY?editors=1010
// HTML
<div id="app">
<v-app id="inspire">
<v-card>
<v-card-title class="headline font-weight-regular blue-grey white--text">Profile</v-card-title>
<v-card-text>
{{ searchedItems }}
<v-subheader class="pa-0">Where do you live?</v-subheader>
<v-autocomplete
v-model="model"
:items="states"
:label="State"
:search-input.sync="filter"
ref="selectExample"
>
</v-autocomplete>
</v-card-text>
</v-card>
</v-app>
</div>
// JS
new Vue({
el: '#app',
data () {
return {
model: null,
filter: '',
searchedItems: [],
states: [
'Alabama', 'Alaska', 'American Samoa', 'Arizona',
'Arkansas', 'California', 'Colorado', 'Connecticut',
'Delaware', 'District of Columbia', 'Federated States of Micronesia',
'Florida', 'Georgia', 'Guam', 'Hawaii', 'Idaho',
'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky',
'Louisiana', 'Maine', 'Marshall Islands', 'Maryland',
'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi',
'Missouri', 'Montana', 'Nebraska', 'Nevada',
'New Hampshire', 'New Jersey', 'New Mexico', 'New York',
'North Carolina', 'North Dakota', 'Northern Mariana Islands', 'Ohio',
'Oklahoma', 'Oregon', 'Palau', 'Pennsylvania', 'Puerto Rico',
'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee',
'Texas', 'Utah', 'Vermont', 'Virgin Island', 'Virginia',
'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
]
}
},
watch:{
filter(newVal){
// I want to get the filtered items list here
this.searchedItems = this.$refs['selectExample'].items
}
}
})
My use case is that when user types in the autocomplete input box, the list of items gets filtered in the dropdown list and I want to use that filtered items.
Vuetify's docs does not mention any prop that exposes this filtered list. Does anyone know how I can get that list in my code?
Thank you in advance :)
VAutocomplete stores it in filteredItems property.
You used ref <v-autocomplete ref="selectExample" so then you can access it like so:
this.$refs.selectExample.filteredItems

V-model using v-for and manipulating array

I can’t figure out in this case how manipulate with v-model change amounts array.
With this code i generated inputs for each item and i want with this inputs change amounts for each item in array eg: if write first input 10 first item amounts array will be 10, 10, 10, 10, 10, 10
I tried to make dynamic v-model prop with index but its not worked.
here is my fiddle : http://jsfiddle.net/eywraw8t/532119/ can someone help me?
category: [{
id: 0,
sub: 'a1',
types: [{
id: 1,
value: "P A",
amounts: [20, 32, 20, 12, 12, 2]
},
{
id: 2,
value: "P B",
amounts: [0, 32, 20, 12, 12, 2]
},
{
id: 3,
value: "P C",
amounts: [30, 32, 20, 12, 12, 2]
},
{
id: 4,
value: "P D",
amounts: [50, 32, 12, 30, 12, 2]
}
]
}]
<div id="app">
<div v-for="item in category">
<h1>
{{item.sub}}
</h1>
<div v-for="type in item.types">
{{type.value}}
<input type="text" v-model="someModel">
<div>
<ul>
<li v-for="amount in type.amounts">{{amount}}</li>
</ul>
</div>
</div>
</div>
</div>
You never want to v-model a value that you have not defined.
In this case, you don't need to v-model anything, you just want to respond to change events and call a method to reset the amounts.
new Vue({
el: "#app",
data: {
category: [
{
id: 0,
sub: 'a1',
types: [{
id: 1,
value: "P A",
amounts: [20, 32, 20, 12, 12, 2]
},
{
id: 2,
value: "P B",
amounts: [0, 32, 20, 12, 12, 2]
},
{
id: 3,
value: "P C",
amounts: [30, 32, 20, 12, 12, 2]
},
{
id: 4,
value: "P D",
amounts: [50, 32, 12, 30, 12, 2]
}
]
},
{
id: 0,
sub: 'a2',
types: [{
id: 1,
value: "P A",
amounts: [20, 32, 20, 12, 12, 2]
},
{
id: 2,
value: "P B",
amounts: [0, 32, 20, 12, 12, 2]
},
{
id: 3,
value: "P C",
amounts: [30, 32, 20, 12, 12, 2]
},
{
id: 4,
value: "P D",
amounts: [50, 32, 12, 30, 12, 2]
}
]
}]
},
methods: {
toggle: function(todo){
todo.done = !todo.done
},
setAllAmounts(type, event) {
type.amounts = type.amounts.map((_) => event.target.value);
}
}
})
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<div v-for="item in category">
<h1>
{{item.sub}}
</h1>
<div v-for="type in item.types">
{{type.value}}
<input type="text" #change="setAllAmounts(type, $event)">
<div>
<ul>
<li v-for="amount in type.amounts">{{amount}}</li>
</ul>
</div>
</div>
</div>
</div>

How can I implement auto suggestion on search field vue js without vue router?

My view like this :
<div id="app">
<h1>Simple typeahead example</h1>
<input placeholder="Search US states" #input="input" v-model="typeahead" />
<ul v-if="!selected && typeahead">
<li v-for="state in states | filterBy typeahead" #click="select(state)">{{ state }}</li>
</ul>
</div>
My vue component like this :
new Vue({
el: '#app',
data: {
selected: null,
typeahead: null,
states: ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']
},
methods: {
select: function(state){
this.typeahead = state
this.selected = state
},
input: function(){
this.selected = null
}
}
});
Demo and full code like this : http://jsfiddle.net/oscar11/tm8k8907/10/
The code above works. But it use vue router
I do not want to use vue router
Is there any other way without using vue router?
Try this:
html:
<li v-for="state in states" v-if="filterBySelect(state)" #click="select(state)">{{ state }}</li>
Method:
filterBySelect (value) {
if (!this.typeahead || this.typeahead.length === 0) return true
return value.toLowerCase().split(this.typeahead.toLowerCase()).length > 1
}